Compare commits

...
42 Commits
Author SHA1 Message Date
github-actions[bot] 7f5408947b Bump versions for v10.80 2026-08-10 20:33:21 +00:00
Lauri Ojansivu 061593c5ee Prepare v10.80 release 2026-08-10 23:32:14 +03:00
Lauri Ojansivu 5fe2192962 CHANGELOG: the translations entry, and the Upcoming groups it exposed.
The entry: which three of the six strings needed translating and why the other
three did not, that each language's own OS_Type and OS_Platform decided the form
its translation takes, that Greek and Korean were NOT copied from because those
two files hold Italian and Japanese there, and that forty files keep the English
placeholder on purpose.

Adding it took the Upcoming section to five entries, and the grouping guard then
found what was already wrong: one group line - the snap one - stood above the
Filesystem integrity entry, which is not a snap change, so an unrelated entry sat
inside that group. Every entry now has a group naming its own area, and the snap
group holds only the two snap entries.

Thanks to xet7 !
2026-08-10 20:45:02 +03:00
Lauri Ojansivu 132a644848 Translations: the new Version-pane strings, in 113 languages.
The Version pane's five category labels and the packaging row were added in
English only, so every other language showed them in English. Three of the six
needed translating at all: Platform, package ("Package") and OS. Database was
already translated in 131 languages - the key existed before and this revived it
- and Meteor and Node are product names that stay as they are in every language,
which is also why the filler ignores a value equal to the English source.

Translated directly, per CLAUDE.md: no external service, and each language's own
existing strings as the reference. Its OS_Type and OS_Platform show which form
that language's translators use - "Typ des Betriebssystems", "Tipo SO", "Тип ОС",
"Käyttöjärjestelmän tyyppi" - so OS is "Betriebssystem" in German, "SO" in
Italian and Portuguese, "ОС" in Russian and "Käyttöjärjestelmä" in Finnish
rather than one spelling imposed on all of them.

Two files were NOT copied from: el's OS_Type and OS_Platform hold Italian, and
ko's hold Japanese. Propagating that would have spread somebody else's mistake
into three more strings, so those two got proper Greek and Korean instead.

Applied through releases/translations/fill-translations.mjs --apply, which
writes ONLY into a placeholder - so no human translation could be overwritten
even by accident. The diff shows it: 292 changed lines across 106 files, and
every one of them is Platform, package or OS. Key order and indentation are
unchanged, every file still parses, verify-human-preference.mjs passes 10/10,
and the 350 node suites pass.

40 language files are left with the English placeholder on purpose - ace, ary,
br, gu-IN, ig, km, mn, oc, or_IN, pa, tk_TM, tlh, ug, ve, vl-SS, vo, wa, wo, xh,
yi, yo, zgh, zu and the en-* variants, which are English by design. A placeholder
that says so is better than a translation I cannot stand behind, and Transifex
can still replace any of these with a human one: nothing here is pushed there.

The backlog is 10285 strings, from 10592.

Thanks to xet7 !
2026-08-10 20:40:53 +03:00
Lauri Ojansivu 5852351d30 Updated translations 2026-08-10 20:35:16 +03:00
Lauri Ojansivu a475afd3d3 Merge pull request #6581 from khuongsatou/codex/apple-glass-pastel-theme-clean
Add Apple Glass Pastel board theme
2026-08-10 18:13:23 +03:00
khuongsatou's projects 4763c94604 Add Apple Glass Pastel board theme
Register appleglasspastel as a fixed special theme, wire its accent and exporter colour, add glass/pastel board surfaces, and guard the picker/docs/runtime preview coverage.
2026-08-10 21:51:21 +07:00
Lauri Ojansivu 539c678199 CHANGELOG: the four v10.79 changes that shipped without an entry.
Every commit of a release belongs in that release's section, and four were not
there: the snap-store table correction, and the three that rewrote CLAUDE.md and
AGENTS.md. They are in v10.79 rather than Upcoming because that is the release
they are in - moving them would be tidier and untrue.

The documentation subsection gains a second entry, so it is grouped by area the
way the rules ask, and a new "and documents how to work on these repositories"
subsection carries the instruction-file entries: who maintains these
repositories and who commits, what is in .tools/ and which changelog format each
repository under it uses, and the correction that TSC is xet7's too.

Thanks to xet7 !
2026-08-10 15:26:36 +03:00
Lauri Ojansivu d0dc7dff98 CHANGELOG: the third MongoDB reader, under Upcoming.
Beside the entry it completes: which server can read which data and why that is
a property of the servers the snap carries, that mongod 4.2 reads only during a
migration, why it brings its own OpenSSL 1.1, that a failure to stage it never
fails a release, what was verified on this machine, and which vintages are still
answered by the page instead.

Thanks to xet7 !
2026-08-10 14:58:07 +03:00
Lauri Ojansivu 71ba0c2dcd Snap: a third MongoDB reader, so a 4.x database migrates instead of stopping.
#6471 again, the other half. The previous commit stopped the crash loop and
explained it; this one removes the reason for it in the case that was actually
reported.

A MongoDB server only starts on data whose featureCompatibilityVersion is at most
one major behind it, so what the snap can READ is decided by which servers it
carries: mongod 7 (FCV 6.0, 7.0) and the MongoDB 3.2 tools (3.2). Everything
between was unreadable, and the WeKan snap has shipped 3.6, 4.0, 4.2, 4.4 and 5.0
over the years. The reported error, twice, is mongod 7 naming the gap: "Try
MongoDB 4.2 or earlier" - FCV 4.0.

So the snap now bundles mongod 4.2 as a third reader, used ONLY to read the old
data during a migration and never as the running database. mongod 4.2 opens FCV
4.0 and 4.2, and the modern importer reads it with the bundled driver, which
supports servers from 4.2 up - the same importer that reads a 6/7 source, not a
second copy of it. The probes run newest-first: 7, then 4.2, then the 3.2 tools,
then the explanatory page.

amd64 and arm64 only. MongoDB publishes no 4.2 for the other architectures, and
they have been FerretDB from their first boot, so there is nothing there to
migrate from.

IT CARRIES ITS OWN OpenSSL 1.1. The 4.2 build links libssl.so.1.1 and
libcrypto.so.1.1, and core24 is Ubuntu 24.04, which ships OpenSSL 3 - without
them the binary does not even load. Both come from one Debian libssl1.1 package,
staged beside the binary and put on LD_LIBRARY_PATH exactly as the 3.2 tools
already are. The filename is resolved by listing the pool rather than pinned,
because point releases roll and a pinned name 404s the day they do; three
archives are tried in turn.

OPTIONAL BY DESIGN. Every failure in the part - download, checksum, OpenSSL,
or the binary not running - ends it with a message and no binary, and the
migration simply does not find one. A release is never failed over a migration
aid, and the snap then behaves as it did before: the unreadable-database page.

VERIFIED, as far as this machine allows: mongod 4.2.25 aarch64 was downloaded,
staged with the Debian bullseye libssl1.1, and RUN here - "db version v4.2.25,
OpenSSL version: OpenSSL 1.1.1w" - then started on a dbpath, forked, and
listened on a port. That is the whole mechanism the snap will use, on a 2026
system, outside a snap. The build itself repeats the --version check and
unstages the binary if it fails. What is not verified is a real snap build and a
real 4.x database; the first upgrade is that test.

Still unreadable, and still handled by the page rather than a migration: 3.4,
3.6, 4.4 and 5.0. Adding mongod 5.0 beside this one would close 4.4 and 5.0 the
same way, at the same cost in size.

Thanks to Philippe-Bentegeac, JDeepix, imlit and xet7 !
2026-08-10 14:57:07 +03:00
Lauri Ojansivu 909496fb8b CHANGELOG: the snap's unreadable-database stop, under Upcoming.
The bug subsection has two entries now, so it is grouped by area and its header
is plural. The entry: what the loop was, why nothing in it could succeed, that
the snap stops and exits 0 rather than letting snapd restart it forever, what
the page tells an admin, and that nothing on that path is deleted or modified.

Thanks to xet7 !
2026-08-10 13:37:17 +03:00
Lauri Ojansivu 562fa02718 Snap: a database this snap cannot read stops and says so, instead of 502.
#6471. A snap upgraded onto a database left by a MongoDB 4.x or 5.x snap served
502 Bad Gateway forever, with the reason only in `snap logs`:

    This version of MongoDB is too recent to start up on the existing data
    files. Try MongoDB 4.2 or earlier.

The snap carries two readers - mongod 7, the server it runs, and the MongoDB 3.2
tools for a 6.09-era database - and nothing in between, so 4.x data opens in
neither. What the code then did is the one thing that cannot work:
migration-control found neither reader could open it and handed back to
mongodb-control, mongodb-control started mongod, mongod failed the same way,
mongodb-control re-ran the migration, three times by its own counter, and then
exited 1 for snapd to restart. Nothing in that loop can succeed - reading those
files needs a binary the snap does not have - and the site was down throughout.

It stops now, and says so where an admin will see it. migration-control tells
"no reader for this vintage" from "unreadable/corrupt" by mongod's own words,
writes $SNAP_COMMON/.mongodb-data-too-old carrying the version mongod named as
still able to read the data, pauses auto-migration and exits 0 - 0, because
snapd restarts a failing service forever and no restart can help. mongodb-control
refuses to start a mongod it knows cannot start. wekan-control serves the
maintenance page with a third reason, data-too-old, at the top of the script and
from inside the database wait loop, so a WeKan already waiting switches over
without a restart.

The page names the version that can still read the files and gives the two ways
forward - revert to the revision that worked, or dump with a MongoDB that can
read it and restore into this version - says that nothing was changed and that
attachments and avatars are files on disk, and drops the auto-refresh and the
spinner the other two maintenance pages have: this is a stop, not a wait, and
the page should not promise that something is happening.

NOTHING IS DELETED OR MODIFIED on this path. The source data is exactly as it
was; the marker is the only thing written, and removing it lets the snap try
again.

tests/snapOldMongoData.test.cjs covers the wiring in all three scripts and then
RUNS the page module - it is standalone Node with no dependencies - to check
what an admin actually sees: 503, the version, "untouched", both remedies, no
refresh, no spinner. The snap docs gain the section an admin searching for that
mongod line will find, with the commands.

Thanks to Philippe-Bentegeac, JDeepix, imlit and xet7 !

Fixes #6471,
2026-08-10 13:35:44 +03:00
Lauri Ojansivu fd67a510f8 CHANGELOG: a new Upcoming section for what came after the v10.79 release.
The v10.79 release renamed the Upcoming heading, and two changes landed after
it: the Filesystem integrity fix, whose entry was written "under Upcoming" when
Upcoming had already become v10.79, and the Version table restructure, which had
no entry at all. So the released section claimed a fix that is not in the
release, and the newest work was invisible.

Both are in a new Upcoming section now - the Filesystem integrity entry moved
out of v10.79 rather than copied, so it appears once - with the summary and the
binaries table the shape requires, and the table stated for what it is: v10.79's
binaries, which nothing here rebuilds.

Thanks to xet7 !
2026-08-10 12:57:57 +03:00
Lauri Ojansivu aed26c6771 Version: one table with combined category rows, over two 50% columns.
The pane was five tables, one per category, and five tables size their columns
independently: "WeKan ® Version" made the first one's label column wide and "OS
Type" made the next one's narrow, so the values started at a different x in
every group and the pane read as five unrelated things.

One table now. Each category is a ROW in it - a th with colspan=2, bold and
start-aligned - so it says what the rows under it are about instead of being a
label with an empty cell beside it. A colgroup of two 50% columns plus
table-layout:fixed puts every label and every value in the same place down the
whole pane, and settingBody.css's 240px header cap is undone for this table
only, since the width is now stated outright and the cap would fight it.

The category title takes the table's own font size deliberately: at the pane
title's size five of them would read as five pane titles and "Version" would be
lost among them.

Two of the repo's own guards caught mistakes on the way, which is what they are
for. tests/jadeCompiles.test.cjs refused `th(colspan=2)`: the Meteor jade
dialect wants the value quoted, and an unquoted one is a build failure rather
than a rendering difference. tests/rtl.test.js refused `text-align: left`: the
label column is on the RIGHT in Arabic and Hebrew, so it is `start`.

tests/versionPaneCategories.test.cjs follows the new shape - exactly one table,
five tr.info-category rows each spanning both columns, the colgroup and
table-layout:fixed that make the 50/50 real, and the category title bold with no
font-size of its own. The row-by-category and no-row-was-lost checks are
unchanged and still pass, so the regrouping moved nothing.

Thanks to xet7 !
2026-08-10 12:54:55 +03:00
Lauri Ojansivu ed0d7a2bad CHANGELOG: repoint commit links after history moved.
A rebase rewrote the commits these entries link to, so the links named commits
that no longer exist and would have 404ed on GitHub. Repointed by
releases/fix-changelog-hashes.sh, which only touches a link no ref in this clone
can reach.

Thanks to xet7 !
2026-08-10 12:51:42 +03:00
Lauri Ojansivu 5a947b6959 CHANGELOG: the blank Filesystem integrity pane, under Upcoming.
First group of the bug fixes, beside the Admin Panel work above it: what the
pane looked like, the one missing helper, and that Blaze reads an undefined
helper as false rather than complaining - which is why three-quarters of the
wiring being right showed as an empty page.

Thanks to xet7 !
2026-08-10 12:51:41 +03:00
Lauri Ojansivu 01c36852da Filesystem integrity showed a blank page: the helper was never added.
Admin Panel / Problems / Filesystem integrity drew nothing at all - the pane
title and then empty space - while Summary went on reporting "7 new problems"
for it.

Everything about the pane looked right, which is why it survived: the menu has a
report-integrity entry, clicking it is handled, the handler sets
tmpl.showIntegrity, the template has `else if showIntegrity.get` and an
+eventStreamReport(stream="integrity") under it. The one missing piece was the
HELPER. showIntegrity() was never added beside showDatabase() and the eight
others, and in Blaze an undefined helper is not an error - it is falsy. So the
branch never ran, the page was blank, and nothing anywhere said why.

The helper is there now, and tests/adminPaneHelpers.test.cjs guards the class
rather than this one pane: every `show*.get` branch in a settings template must
have a helper of that name in that template's own .js, and a ReactiveVar behind
it. The templates are FOUND, not listed, so a pane added later is covered
without editing the test. It also names Filesystem integrity's four wiring
points one by one, because that is the pane that was three-quarters wired.
Checked in the failing direction: removing the helper again fails the test with
the reason.

Thanks to xet7 !
2026-08-10 12:51:41 +03:00
github-actions[bot] afcb9353ee Bump versions for v10.79 2026-08-10 02:07:28 +00:00
Lauri Ojansivu 1d9222eb81 Prepare v10.79 release 2026-08-10 05:06:24 +03:00
Lauri Ojansivu 4588fb8b3d Updated translations. 2026-08-10 05:05:06 +03:00
Lauri Ojansivu fd3a381cd6 CHANGELOG: the packaging row's label is translated, its value is not.
Folded into the Version-pane entry rather than added as a second one: the
release ships one feature, and "we renamed the key afterwards" is not a thing a
reader of the release notes needs to follow.

Thanks to xet7 !
2026-08-10 03:52:34 +03:00
Lauri Ojansivu 5091c3883a Version pane: the packaging row is package, and its value is never translated.
The label was `Platform_packaging` / "Installed as". It is `package` / "Package"
now: a short key for a short column, in the vocabulary the rest of the pane uses.

The half that matters more is the VALUE. bundle.zip, Snap, Docker and Sandstorm
are the names of the things themselves - a package format, a store, a product -
not words describing them, so they are not translated anywhere and none of them
is an i18n key. What an admin reads in the pane is then the same string they can
put in an issue, search the docs for and grep a log with, in every language; a
translated "Ohjelmapaketti" in a Finnish screenshot would match nothing anybody
can look up.

The test carries both halves rather than the comment alone: the label must be
the translated key, the value must be printed straight from
statistics.platform.packaging with no {{_ }} around it, and none of the four
names may exist as an i18n key - which is how "translate it somewhere else
later" is caught. Checked in the failing direction too: wrapping the value in
the translation helper fails with the reason.

Thanks to xet7 !
2026-08-10 03:52:18 +03:00
Lauri Ojansivu de7770f211 CHANGELOG: the Version pane's five tables, under Upcoming.
Its own subsection between the new features and the bug fixes, where an Admin
Panel reorganisation goes: what the pane was, what the five categories are and
why reactivity and DDP moved to Meteor, the new "installed as" row and the order
its detection asks its questions in, and that the heading size is a test rather
than a promise.

Thanks to xet7 !
2026-08-10 03:42:10 +03:00
Lauri Ojansivu dcc6c8fe5d Version pane: five tables with a heading each, and what WeKan is installed as.
Admin Panel / Settings / Version was ONE table of 38 rows. The WeKan version,
the OS load average, the DDP transport and a V8 heap counter were the same kind
of thing in it: one flat list, read top to bottom, with no way to jump to the
part you came for.

Five tables now, each under a small heading, in the order somebody debugging
reads them - Platform (what this IS), OS (what it runs on), Meteor (how it talks
to the client: reactivity, reactivity order, DDP transport), Database (type,
versions, commits, storage engine, OpLog, sessions) and Node (version, heap,
memory). Reactivity and DDP moved to Meteor, where they belong: they are how the
client is fed, and they were the two rows most often read as database settings.
Whether an OpLog EXISTS stays with the database, because that is a property of
it. No row was dropped; a test lists all 38 by name and requires each to still
be shown.

NEW ROW: what WeKan is installed as - bundle.zip, Snap, Docker or Sandstorm. It
is the first thing a support answer turns on, and the pane never said it: the
same version keeps its data somewhere else, carries a different database and
gives the admin different reach in each of the four. models/lib/platformPackaging.js
detects it, most-specific-first: an explicit WEKAN_PACKAGING wins (a packaging
that knows what it is should say so, and it is how a future .deb or chart names
itself), then Sandstorm, then snapd's own SNAP/SNAP_NAME, then a container
runtime's marker file, then the bundle. Sandstorm and Snap are asked BEFORE the
container markers on purpose: a grain is a container, and a confined snap can
look like one, so the other order answers "Docker" for both. It claims nothing
it cannot know - there is no "source checkout" answer, because a `meteor run`
and an unpacked bundle are identical from inside the process.

The detection is a pure function taking the environment, the Sandstorm flag and
a file-exists callback, so all nine of its tests run here without a snap, a
container or a grain - including that an empty SNAP is not a snap, that an empty
WEKAN_PACKAGING falls through rather than blanking the field, and that an
unreadable root answers bundle.zip instead of throwing an admin's Version page
away.

The headings are SMALLER than the pane title above them, and a test compares the
two font sizes rather than trusting the CSS to stay that way: five headings at
1.25rem would read as five pane titles and "Version" would be lost among them,
and an unstyled h3 - the browser default here - is larger still. Six new English
strings; the other languages fall back to English until translated, as usual.

tests/clientBundleImports.test.cjs caught the new stylesheet before it could
matter: package.json sets meteor.mainModule, so a .css nobody imports is simply
not in the bundle. It is imported from client/features/settings.js now.

Thanks to xet7 !
2026-08-10 03:40:12 +03:00
Lauri Ojansivu 3170b70f51 CHANGELOG: the next base's six architectures, under Upcoming.
Its own group under the bug fixes, beside the snap builds group it belongs
with: what was missing from snapcraft-core26.yaml, why nothing could have
noticed, and why adding the platform without the t64 package names would have
been nominal.

Thanks to xet7 !
2026-08-10 03:04:32 +03:00
Lauri Ojansivu 664b8fde6f The next base builds all six architectures too, armhf included.
snapcraft.yaml declares six platforms - amd64, arm64, armhf, ppc64el, riscv64,
s390x - and every one of them is built: amd64 and arm64 natively, the other four
on Launchpad. snapcraft-core26.yaml declared FIVE. armhf was missing, and nothing
could notice: that file is not built by any release, it is the next base kept so
the move can be tested before it is made. The day core26 becomes the base, armhf
would simply stop being published and the only symptom would be a store column
going stale, exactly as wekan-ondra's armhf did at 0.22.

Adding the platform alone would have been nominal. The same file still carried
the PRE-t64 stage-package names - libssl3, libcurl4, libgoogle-perftools4 - and
those are precisely what failed armhf on core24 twice: Ubuntu's 64-bit time_t
transition renamed them, the 64-bit architectures kept a compatibility Provides
so the old spelling resolves there, and armhf did not. So armhf on core26 would
have failed on the first thing it tried, in the way this repository has already
debugged. It has the t64 names now. Its Caddy branch already mapped armhf to
Go's armv7 name; the comment saying that branch is unreachable is no longer true
and says so.

Two guards, both checked in the failing direction as well:
tests/releaseSnapArches.test.cjs now requires the two snapcraft files to declare
the SAME set of architectures - removing armhf from core26 fails it with the
reason - and the stage-package check runs over BOTH files rather than only the
one the release builds, so the next base cannot drift back to a name that breaks
on one architecture only.

Nothing here changes what the release builds today: core24 stays the built base,
and wekan's armhf snap is still waiting on the Caddy armhf fix in the upcoming
release.

Thanks to xet7 !
2026-08-10 03:04:11 +03:00
Lauri Ojansivu cf0c347b2e Snap CPU platforms: what the store actually holds at 10.78, and why.
The table said "as of 10.76" and marked every empty square the same way: "built
by snapcraft.yaml but that snap has no revision for it yet - uploading one is all
that is needed". For eight of the twelve squares that is not true, and it points
whoever reads it at the wrong job.

Three marks now, because there are three situations. wekan's armhf is BUILT by
the release and missing from the store: snapcraft.yaml declares it,
snap-launchpad builds it, and it has been failing - most recently on Caddy, which
publishes no linux_armhf archive because its asset names are Go's, fixed for the
next release. The exotic squares of wekan-ondra and wekan-gantt-gpl are not
pending uploads at all: the snap-variants job has four matrix entries, each
variant on amd64 and arm64 on GitHub runners, and the ppc64el/s390x/riscv64/armhf
builds come from snap-launchpad, which builds only the `wekan` name. Nothing will
ever upload those unless the variant job learns Launchpad remote builds under the
variant snap names. And wekan-ondra's armhf 0.22 stays a fossil, now said
explicitly: there is no newer revision to promote AND nothing currently builds
one.

riscv64 moved from missing to published since 10.76, so wekan is five of six.
Every published architecture is on all four channels, which is the earlier
release-to-all-channels work holding.

Thanks to xet7 !
2026-08-10 02:53:18 +03:00
Lauri Ojansivu bf1f7aea47 CLAUDE.md and AGENTS.md: TSC is xet7's too, under another organisation.
The previous commit read Secretchronicles/TSC's remote, saw it was not a wekan/
repository, and concluded it was somebody else's project xet7 contributes to. It
is his: the organisation is Secretchronicles rather than wekan, and that is the
only difference. His GitHub profile says it in three words - "WeKan and TSC
maintainer" - and the files now cite it, so the next reader checks a source
instead of inferring from a remote URL as this one did.

So maintainer mode covers it - commit directly to devel, no pull request, same
author, no AI attribution - and the files say which .tools/ repository actually
is somebody else's: sandstorm-io/sandstorm, cloned for reference.

What does NOT follow from maintaining it is WeKan's house style. TSC keeps its
own GNU ChangeLog file and its own release process, exactly as the CHANGELOG
section below already said, because a project is read on its own terms.

Thanks to xet7 !
2026-08-10 02:04:31 +03:00
Lauri Ojansivu d077948115 CLAUDE.md and AGENTS.md: what is in .tools/, and each repository's changelog format.
THE LAYOUT OF .tools/. It was one sentence naming three clones. It is now the two
kinds of thing that directory actually holds, because they are treated
differently. Companion git repositories - wekan/FerretDB on main-v1,
wekan/node-patches and wekan/mongo-tools-patches on main, Secretchronicles/TSC on
devel, sandstorm-io/sandstorm - each with their own history, branches, changelog
and release flow, cloned on demand by build.sh's ensure_tool_repo; a commit in
WeKan is never a commit in one of them. And unpacked toolchains that are
downloads rather than repositories: node-v<version>-linux-<arch>, go with its
gopath/gomodcache/gocache, .meteor when HOME points at .tools, the TSC AppImage.
Delete and re-fetch those freely.

TSC and sandstorm are NOT xet7's repositories, and the ownership paragraph at the
top no longer implies they are. The commit author is the same there; the branch,
the contribution process and the changelog format are that project's call.

NO CLAUDE.md OR AGENTS.md UNDER .tools/. node-patches and mongo-tools-patches
each had a pair, and they were removed: the rules are identical for all of these
repositories and a second copy drifts from the first. These two files are where
they live. A fact true of one repository only belongs in that repository's own
README.md or docs/ - and an instruction file found there is to be removed rather
than updated.

CHANGELOG FORMAT, PER REPOSITORY. A table of the five that come up, because they
are not all the WeKan format: wekan/wekan, node-patches and mongo-tools-patches
use it; wekan/FerretDB keeps UPSTREAM FerretDB's (## [v1.48.0](tag) (date) with
### New Features/Fixed/Other Changes bullets ending "by @xet7"); and TSC uses GNU
ChangeLog - a "YYYY-MM-DD  Name  <email>" header over tab-indented "* Fix: ..."
entries ending "(by Name)", in a file called CHANGELOG with no extension. The
reason is the reader: a FerretDB release is read beside upstream's, and a TSC
entry beside a decade of GNU ChangeLog entries. When this file and the file being
edited disagree, the file being edited wins.

AGENTS.md had drifted from CLAUDE.md - it still described a FerretDB subdirectory
at the repo root and told the release step to run from there. The two files are
now identical apart from their first and third lines, which name the tool that
reads them.

Thanks to xet7 !
2026-08-10 01:55:46 +03:00
Lauri Ojansivu 35dd10b89f CLAUDE.md and AGENTS.md: who maintains these repositories, and who commits.
The instruction files opened with an identity CHECK - "maintainer mode only when
the identity is exactly Lauri Ojansivu <x@xet7.org>" - which says what to do with
an identity but never says whose repositories these are. They are xet7's: WeKan,
the FerretDB v1 fork, node-patches and mongo-tools-patches. That is now the first
thing both files say, and the commit author follows from it rather than from a
conditional.

Two rules are spelled out under it. No commit, pull-request body or CHANGELOG
line ever attributes work to an AI - no Co-Authored-By, no "Generated with", no
assistant or model name - and CODE_OF_CONDUCT.md is cited as where that comes
from ("mention only those participants that are human"); a "Thanks to ... and
xet7 !" line credits people. And a missing or wrong git identity in one of these
checkouts is to be SET, not worked around: the .tools/ clones build.sh makes can
come up with no user.name/user.email at all - mongo-tools-patches did - which
would author a commit as whatever the machine's default is.

Contributor mode is unchanged in substance: a different person's identity, in
their own fork or clone, still means a branch and a pull request, and that pull
request carries no AI attribution either.

Thanks to xet7 !
2026-08-10 01:45:21 +03:00
Lauri Ojansivu cf000d000a CHANGELOG: the armv6 Docker platform, and the CPU-platform pages.
Two entries under Upcoming. The armv6 one goes in the "Raspberry Pi 1 and
Zero" group beside the bundle that already ships: what TARGETVARIANT changes,
why the base image is asked what it publishes at all, and that debian:trixie
has arm/v5 and arm/v7 and nothing between them.

The documentation subsection covers the new Docker CPU-platforms page, the
snap page's armv6 section and bundle table, and the FerretDB v1 page's
architecture list. The In short paragraph no longer claims armv6 ships a
Docker image today - it says the image is wired and gated.

Thanks to xet7 !
2026-08-10 01:36:08 +03:00
Lauri Ojansivu 5ec9f3ae5b Document the CPU platforms of the Docker image, beside the snap's.
"Which CPUs is this published for, and why not that one" was answerable for
the snap and nowhere else, so the same page now exists for the image:
docs/Platforms/FOSS/Container/Docker/CPU-platforms.md. It carries the platform
matrix with each platform's TARGETARCH, TARGETVARIANT and bundle, how the set
is decided on every release from what the base image publishes and which
bundles landed, the three names that differ between Docker, Debian and the
WeKan bundles, and one section per platform that is deliberately NOT an image:
loong64 (no base image exists at any tag), armv6 (gated on a base with
arm/v6), armv7 (the one 32-bit ARM slot must carry the armhf baseline) and the
Windows and macOS bundles. It ends with why the FerretDB image covers more
platforms than the WeKan one - FROM scratch around a static Go binary needs no
userland at all.

The snap's page gains the matching armv6 section - the Snap Store has no armv6
architecture, and its only 32-bit ARM is armhf, which an ARMv6 board cannot
run - and a table of all fifteen bundles against which six become snaps, so
"it is missing" and "it cannot be there" stop looking alike. The two pages
link each other, because the answer differs between them.

docs/Databases/FerretDB/1/README.md said the per-architecture FerretDB binary
was embedded in the bundles "for ppc64le, s390x, riscv64". Every bundle
carries one; those three are part of a longer list of platforms where it is
the DEFAULT because MongoDB publishes no server. It now lists all seventeen
built binaries and separates the three 32-bit ARM builds that are not variants
of each other: armhf is GOARM=7, armv6 is GOARM=6, armel is GOARM=5 software
floating point.

Thanks to xet7 !
2026-08-10 01:35:51 +03:00
Lauri Ojansivu f342d54d18 Docker: read TARGETVARIANT, and make linux/arm/v6 a candidate platform.
TARGETARCH does not identify a 32-bit ARM platform: linux/arm/v6 and
linux/arm/v7 both arrive as TARGETARCH=arm, and the generation is in
TARGETVARIANT. The Dockerfile's case mapped arm straight to armhf, so the
moment armv6 existed as a bundle an ARMv6 build would have been handed the
armhf zip - ARMv7-A instructions for a CPU that cannot run them. It now
branches on the variant: v6 takes armv6, v7 and an unset variant take armhf,
and anything else exits. v5 is armel, which Go builds and Node.js does not
exist for, so there is no bundle and refusing is the only honest answer.

linux/arm/v6 joins the docker job's optional platform list, and the release
now asks a question it never asked before: does the BASE IMAGE publish this
platform? For every other architecture that is uninteresting, because a base
that lacks one fails the build. For 32-bit ARM it does not fail - containerd
treats a LOWER arm variant as compatible, so a linux/arm/v6 request against a
base with arm/v5 and arm/v7 resolves to arm/v5, Debian armel, SOFT float, and
the image would be built on a userland whose loader cannot start the
hard-float node-armv6 in the bundle. A silent downgrade is worse than a
dropped platform.

So the job reads the base name out of the Dockerfile - no second copy of it -
asks docker buildx imagetools inspect what that base publishes, and drops a
candidate it lacks with a warning saying why. debian:trixie is 386, amd64,
arm64/v8, arm/v5, arm/v7, ppc64le, riscv64, s390x: no arm/v6, because Debian
has no ARMv6 port at all. The armv6 bundle zip is unaffected, and the image
platform turns itself on the day a base publishes the variant.

VERIFIED: debian:trixie's manifest list was read from the registry rather than
assumed, and the decide step was extracted and run against both that list
(armv6 drops, the other seven build) and a base that does publish arm/v6
(armv6 included, paired with the armv6 bundle). tests/releaseDockerPlatforms
pins the variant split, the refusal of v5, the platform-to-bundle pairing and
that both loops ask the base - the last so that deleting the check cannot
quietly become an image whose Node.js will not start.

Thanks to xet7 !
2026-08-10 01:35:38 +03:00
Lauri Ojansivu d9e4cd57cb Add the armv6 bundle: Raspberry Pi 1 and Zero.
Every piece of the chain now exists, and the missing one was Node.js.
nodejs.org dropped its ARMv6 binaries after Node 11 and unofficial-builds
has none, so wekan/node-patches gained an armv6 target (V8 still accepts
--arm-arch=armv6 and configure.py still carries is_arch_armv6() with
`vfp` among valid_arm_fpu); wekan/FerretDB and wekan/mongo-tools-patches
gained GOARM=6 targets beside their armhf ones.

Their armel is GOARM=5 and WOULD run on these boards, which is why it
looks like a substitute and is not one: GOARM=5 does floating point in
software and ARMv6 boards have VFPv2.

The bundle builds in a linux/arm/v6 container, takes node-armv6, and
releases/resolve-node-source.sh resolves it - naming linux-armv6l as the
upstream spelling even though nothing upstream will ever answer to it, so
the search it prints is honest about where it looked.

NO SNAP, and that is not an oversight: the Snap Store has no armv6
architecture at all. Its only 32-bit ARM is armhf, which is ARMv7-A
hard-float and will not run on an ARMv6 board. So armv6 ships as a
bundle zip and a linux/arm/v6 Docker image, and
models/lib/snapArchitectures.js records that reason in
NOT_SNAP_ARCHITECTURES beside i386's and armv7's.

Four tests found the four places a new platform has to be registered,
which is what they are for: releases/expected-assets.sh (or "Release all
missing" never notices it is absent), the resolver mapping table, the
non-native bundle list, and the snap-platform exemption. Each list was
updated rather than the guard loosened.

WHAT IS NOT VERIFIED: none of these binaries has been built. The Node.js
one is a multi-hour ARM cross compile and the first CI run is its test.
Everything checkable from source was checked - V8's accepted --arm-arch
values, configure.py's ARM handling, Go's GOARM semantics, and that
zlib's ARM SIMD is gated on arm_fpu=="neon" so an armv6 build selects
scalar code and needs none of the NEON patching armv7 does.

Thanks to xet7 !
2026-08-09 23:38:43 +03:00
Lauri Ojansivu 3d9ee1f9fc CHANGELOG: the win-arm64 bundle, and why armv5/armv6 cannot be added.
Thanks to xet7 !
2026-08-09 23:06:38 +03:00
Lauri Ojansivu 8bb7b9ba62 Add the win-arm64 bundle: every binary it needs was already published.
Windows on ARM is a bundle WeKan could always have shipped and simply
did not. All three suppliers publish it:

  Node.js       nodejs.org, node-v24.19.0-win-arm64.zip, officially
  FerretDB      wekan/FerretDB, ferretdb-win-arm64.exe
  mongo-tools   wekan/mongo-tools-patches, every tool as -win-arm64.exe

releases/resolve-node-source.sh gains the platform and resolves it live
to nodejs.org with a published SHA256, so it needs no node-patches build
at all - the asset name is recorded anyway, for the day it does.

The job is build-win64 with the architecture changed. It builds on the
x64 Windows runner, like win32 does: the Meteor bundle is JavaScript,
the native modules are installed with --ignore-scripts and are not
compiled for the runner's architecture either way, and the only
architecture-specific things in the zip are the three binaries above,
which are downloaded rather than built.

Registered where a new bundle has to be registered or it is invisible:
release-notes needs it, or the provenance rows are collected before the
job that writes them has finished; and releases/expected-assets.sh lists
it, or "Release all missing" never notices it is absent.

WHAT CANNOT BE ADDED, checked at the same time: armv5, armv6 and armel.
FerretDB and the MongoDB tools publish armel - they are Go, and Go still
targets it - but Node.js does not exist for any of the three. nodejs.org
publishes no 32-bit ARM at all for v24.19.0, unofficial-builds has no
armv6l, and wekan/node-patches builds node-armhf and node-armv7 only. No
Node.js means no bundle, so no Docker image and no snap either. The Snap
Store has no armv5 or armv6 architecture in any case; its only 32-bit
ARM is armhf, which WeKan already publishes.

tests/cpuExecWiring.test.cjs counted four non-Linux bundle jobs and
found five. Rather than change the 4 to a 5, it now derives the count
from the jobs and checks that EACH of them strips the Linux-only
cpu-exec and qemu-x86_64 - which is what the number was standing in for,
and what a bare count cannot tell you when it changes. Verified it fails
when build-win-arm64 does not strip its own copy.

Thanks to xet7 !
2026-08-09 23:05:00 +03:00
Lauri Ojansivu c892540f43 Caddy: the same armhf mapping in every snapcraft file that fetches it.
snapcraft.yaml was fixed; snapcraft-core26.yaml had the identical
passthrough default and was missed. core26 does not build armhf today,
so nothing failed there - which is exactly why it would have been
rediscovered by a release rather than by a test the day an armhf build
was added.

The guard now checks EVERY snapcraft file that fetches Caddy rather than
the first one it finds, which is the mistake that let this through: the
original test read `yaml.indexOf('case "${CRAFT_ARCH_BUILD_FOR}" in')`
and got the WEKAN_ARCH case above it, so it tested the wrong block while
looking like it worked. It is scoped to the block containing CADDY_ARCH
now. It deliberately does not require two such files - WeKan ships
core24 because that is what may publish to the stable channel, and
either file could be removed one day - so the invariant is about the
files that DO fetch Caddy, not how many there are.

Also pins what makes downloading the official binaries sufficient: the
bundled Caddyfile is `:8080 { reverse_proxy localhost:3000 }` and
nothing else, so every directive is in the standard distribution and no
xcaddy build is needed. A third-party module's directive would change
that and would not fail until Caddy refused the config at runtime, so
the test names the ones that would.

Thanks to xet7 !
2026-08-09 22:51:38 +03:00
Lauri Ojansivu 08f41037f3 CHANGELOG: the Caddy armhf mapping and the Snap Store retry.
Thanks to xet7 !
2026-08-09 22:44:56 +03:00
Lauri Ojansivu 4e9be22f95 Snap: Caddy has no armhf archive, and a store hiccup is not a bad snap.
Two failures in the v10.78 snap jobs, neither of them a problem with
WeKan.

ARMHF ASKED FOR A CADDY ARCHITECTURE THAT DOES NOT EXIST. With the
libcurl4t64 fix in, the armhf build got past the stage-packages and died
further along:

    :: Downloading Caddy 2.11.4 (linux/armhf) from GitHub releases...
    :: + curl -fsSL -o /tmp/caddy.tar.gz https://github.com/caddyserver/
       caddy/releases/download/v2.11.4/caddy_2.11.4_linux_armhf.tar.gz
    :: curl: (22) The requested URL returned error: 404
    'override-build' in part 'caddy' failed with code 1.

Caddy is built by Go and its release assets carry GO's architecture
names, not Debian's. There is no linux_armhf archive and there never has
been - the 32-bit ARM ones are armv5, armv6 and armv7 - and the case
statement had no armhf branch, so it fell through to a default that
passed the Debian name straight into the URL. The "fall back to the
pinned version" path then retried the SAME wrong name, so the failure
read as "Caddy stopped publishing this architecture" when it was this
file's mapping all along.

armhf maps to armv7, not armv6: Debian armhf's baseline is ARMv7-A with
VFPv3-D16 hard-float, and Go's armv7 build is GOARM=7, which is exactly
that. This is NOT the armhf/armv7 distinction that matters for Node.js
in wekan/node-patches - that one is about NEON, and GOARM=7 does not use
NEON. Checked against the actual release: all six mapped URLs answer,
and linux_armhf 404s.

The default branch now names the problem and stops, instead of guessing
a name and letting a 404 blame the wrong project.

THREE GOOD SNAPS WERE LOST TO A STORE HICCUP. riscv64, ppc64el and s390x
each built on Launchpad, downloaded, and were then refused:

    Status: error while processing
    Issues while processing snap:
    - binary_sha3_384: Error checking upload uniqueness.

That is the store failing its OWN duplicate check on a digest it had
just computed - a server-side error, not a bad snap - and the message
the job printed was about 'is not a valid file', credentials and ACLs,
none of which applied. The upload is retried three times with a backoff
now, and the give-up message says the snap is fine and nothing here
needs changing.

The retry stays narrow on purpose: a rejected file, unparseable
credentials or a missing ACL will be rejected identically three times,
and retrying those only buries the one message that says what to fix.
The classifier is tested against all four, not just the one that
happened.

New checks in tests/snapStagePackages.test.cjs (every snap architecture
maps to a Caddy asset that exists, every build-for has a mapping, and -
negatively - an unmapped one fails loudly instead of 404ing) and in
tests/provenanceTable.test.cjs (the processing failure is retried, the
four unretryable messages are not, and the give-up message does not send
somebody debugging a build that succeeded). Verified the Caddy guard
fails when the armhf branch is removed.

Thanks to xet7 !
2026-08-09 22:44:22 +03:00
Lauri Ojansivu 74dfacd76e CHANGELOG: a new Upcoming section for the amd64 provenance fix.
Its commit landed after "Bump versions for v10.78", so it did not ship
in v10.78. The entry had been written into that section anyway, because
the release was already cut by the time it was added; it moves out to
Upcoming, and the sentence in v10.78 that pointed at it says what the
other half was instead of pointing at an entry that is no longer there.

Also records #6580 (CHANGELOG.md is too big for GitHub to render or
blame) under TODO Later rather than leaving it looking unexamined.
Splitting the file by year was tried and abandoned: git records no move,
so a plain `git blame` on a per-year file credits every line to the
split and only `git blame -C` reaches the real history, which editors do
not pass by default. Trading working local blame on eleven years of
entries for a smaller file is the wrong way round, and reverting a split
does not undo it - the restored lines then blame to the revert - so the
note says what a real fix would have to do instead.

Thanks to mimZD and xet7 !
2026-08-09 22:28:22 +03:00
Lauri Ojansivu 058c74e9c8 CHANGELOG: the amd64 provenance script paths.
Thanks to xet7 !
2026-08-09 18:40:28 +03:00
Lauri Ojansivu e596805194 amd64: the provenance scripts were never found, only never complained.
The v10.78 amd64 build failed with exit 127 after the bundle was zipped
and checksummed:

    a95d331b…  wekan-10.78-amd64.zip
    bash: releases/record-provenance.sh: No such file or directory
    bash: releases/ferretdb-latest-tag.sh: No such file or directory

The step runs `cd .build` first, so nothing relative in it means what it
looks like it means. That is TWO bugs, and only the second one had ever
been visible:

The SCRIPT path. `bash releases/record-provenance.sh` resolves against
.build/, which has no releases/. It had printed "No such file or
directory" on every run since it was written, and the `|| true` on the
end swallowed it - so amd64 had never recorded any provenance at all,
and the only symptom was its absence from the release-notes table. The
missing-directory fix in the previous commit therefore fixed the half
that was visible and left the half that was not.

The OUTPUT path, fixed previously: `mkdir -p provenance` made
.build/provenance while upload-artifact looked at provenance/ from the
workspace root.

What turned it loud is that the FerretDB tag lookup added in that same
commit is an ASSIGNMENT. Under `set -e` - and every GitHub `run:` is
`bash -e` - `VAR="$(cmd)"` ends the step when cmd fails, so a line that
had been silently doing nothing for months became a hard 127 that failed
the whole amd64 build. Every path in that step is absolute now, and
every FERRET_TAG assignment across all seven sites ends `|| true`: the
bundle is the deliverable, and which version string reaches a markdown
cell is not worth failing a good build for.

Only amd64's step cds; the other six run from the workspace root, which
matches what the v10.77 run produced - they all uploaded provenance and
amd64 did not.

Two more checks in tests/provenanceTable.test.cjs, now 22. One walks
back from every provenance call to its step header and requires an
absolute path when a `cd` runs inside that step - which is the general
form of this bug and would have caught it. The other requires every
FERRET_TAG assignment to tolerate failure. Both verified to fail when
the v10.78 shapes are put back.

Thanks to xet7 !
2026-08-09 18:39:38 +03:00
200 changed files with 5803 additions and 489 deletions

No files matched your search

+464 -23
View File
@@ -39,7 +39,8 @@ name: Release All Platforms
# not compiled here) and embeds it
# - release: creates the GitHub Release with the newest CHANGELOG.md notes and
# uploads the core wekan-<version>-{amd64,arm64}.zip bundles
# - build-win64 / build-mac-arm64 / build-extra-arches: built AFTER release, each
# - build-win64 / build-win-arm64 / build-mac-arm64 / build-extra-arches: built
# AFTER release, each
# rebuilds the amd64 bundle's native modules for its platform (Windows,
# macOS arm64, and QEMU-emulated ppc64le/s390x/riscv64) and attaches
# its .zip to the Release. Windows/macOS strip the Linux FerretDB back
@@ -623,21 +624,40 @@ jobs:
cat "wekan-${VERSION}-amd64.zip.sha256sum"
# Where this bundle's binaries came from, for the release notes.
#
# $GITHUB_WORKSPACE, not a relative path: this step ran `cd .build`
# above, so `mkdir -p provenance` made .build/provenance while the
# upload-artifact below looks at provenance/ from the workspace root.
# It found nothing - "No files were found with the provided path:
# provenance/" - and amd64, the platform most people download, was the
# one bundle missing from the v10.77 release-notes table. Every other
# build job records from the workspace root, which is why only this one
# was affected.
# EVERY path here is absolute, because this step ran `cd .build` above
# and NOTHING relative means what it looks like it means from inside
# it. Both halves of that bit:
#
# The SCRIPT. `bash releases/record-provenance.sh` resolves against
# .build/, which has no releases/ - so it was
# bash: releases/record-provenance.sh: No such file or directory
# every single run, and the `|| true` on the end swallowed it. amd64
# had therefore never recorded anything, and the only visible symptom
# was its absence from the release-notes table.
#
# The OUTPUT. `mkdir -p provenance` makes .build/provenance, while
# the upload-artifact below looks at provenance/ from the workspace
# root - "No files were found with the provided path: provenance/".
#
# Every other build job records from the workspace root, which is why
# only this one was affected by either.
#
# The `|| true` stays on the record calls: a release note must not fail
# a build that produced a good bundle. It is exactly what hid this for
# so long, so the absolute paths are what make it honest rather than
# the error handling.
mkdir -p "$GITHUB_WORKSPACE/provenance"
PROVENANCE_FILE="$GITHUB_WORKSPACE/provenance/amd64.tsv" bash releases/record-provenance.sh \
PROVENANCE_FILE="$GITHUB_WORKSPACE/provenance/amd64.tsv" bash "$GITHUB_WORKSPACE/releases/record-provenance.sh" \
'amd64' 'Node.js' "${NODE_FROM:-}" "${NODE_FULL:-$NODE_VERSION}" \
"${NODE_URL:-}" \
"${NODE_SHA256:-}" || true
FERRET_TAG="$(bash releases/ferretdb-latest-tag.sh)"
PROVENANCE_FILE="$GITHUB_WORKSPACE/provenance/amd64.tsv" bash releases/record-provenance.sh \
# ...and `|| true` here too, for the same reason: this is an
# ASSIGNMENT, so under `set -e` a missing script ends the step with
# exit 127 - which is what this line did on v10.78 before the path was
# made absolute, failing the whole amd64 build after the zip was
# already built and checksummed.
FERRET_TAG="$(bash "$GITHUB_WORKSPACE/releases/ferretdb-latest-tag.sh" || true)"
PROVENANCE_FILE="$GITHUB_WORKSPACE/provenance/amd64.tsv" bash "$GITHUB_WORKSPACE/releases/record-provenance.sh" \
'amd64' 'FerretDB' 'wekan/FerretDB' "${FERRET_TAG:-latest}" \
'https://github.com/wekan/FerretDB/releases/latest/download/ferretdb-amd64' \
"${FERRET_SHA:-}" || true
@@ -842,7 +862,7 @@ jobs:
'arm64' 'Node.js' "${NODE_FROM:-}" "${NODE_FULL:-$NODE_VERSION}" \
"${NODE_URL:-}" \
"${NODE_SHA256:-}" || true
FERRET_TAG="$(bash releases/ferretdb-latest-tag.sh)"
FERRET_TAG="$(bash releases/ferretdb-latest-tag.sh || true)"
PROVENANCE_FILE=provenance/arm64.tsv bash releases/record-provenance.sh \
'arm64' 'FerretDB' 'wekan/FerretDB' "${FERRET_TAG:-latest}" \
'https://github.com/wekan/FerretDB/releases/latest/download/ferretdb-arm64' \
@@ -1230,7 +1250,7 @@ jobs:
"${node_url:-}" \
"${node_sha256:-}" || true
if [ -s bundle/ferretdb.exe ]; then
FERRET_TAG="$(bash src/releases/ferretdb-latest-tag.sh)"
FERRET_TAG="$(bash src/releases/ferretdb-latest-tag.sh || true)"
PROVENANCE_FILE=provenance/win64.tsv bash src/releases/record-provenance.sh \
'win64' 'FerretDB' 'wekan/FerretDB' "${FERRET_TAG:-latest}" \
'https://github.com/wekan/FerretDB/releases/latest/download/ferretdb-win64.exe' \
@@ -1380,6 +1400,353 @@ jobs:
echo "::error::build-win64 FAILED. The ::error:: line in this job's log, above, says which step and why."
fi
# Build win32 (32-bit Windows) bundle.
#
# BEST-EFFORT, like mac-x64 and the exotic Linux arches: nodejs.org has no
# 32-bit Windows Node 24 at all (upstream removed the build in Node 23) and
# unofficial-builds has none either, so this bundle's node.exe can only come
# from wekan/node-patches. Until node-win32.exe is published there the preflight
# SKIPS this job (a warning, not a red failure); it returns on its own the
# release after it appears.
#
# The runner is 64-bit and the bundle is 32-bit. There is NO 32-bit Windows
# Node 24 to install (that is the whole reason the fork exists), so setup-node
# runs the runner's normal x64 Node to DRIVE the build, and the native modules
# (bcrypt) are cross-compiled to ia32 by passing npm_config_arch=ia32 in the
# rebuild step below - node-gyp then fetches the ia32 headers and builds Win32
# binaries. The shipped node.exe is the fork's 32-bit node-win32.exe.
# Windows on ARM. Every binary this bundle needs is published: nodejs.org
# builds node-<version>-win-arm64.zip itself, wekan/FerretDB publishes
# ferretdb-win-arm64.exe and wekan/mongo-tools-patches publishes the tools
# as -win-arm64.exe - so this is a bundle WeKan could always have shipped
# and simply did not.
#
# It builds on the x64 Windows runner, like win32 does: the Meteor bundle is
# JavaScript, the native modules are installed with --ignore-scripts and are
# not compiled for the runner's architecture either way, and the only
# architecture-specific things in the zip are the three binaries above,
# which are downloaded rather than built.
build-win-arm64:
needs: [prepare, build-amd64, release]
runs-on: windows-latest
timeout-minutes: 60
env:
VERSION: ${{ needs.prepare.outputs.version }}
steps:
# Checked out into src/ so start-wekan.bat and snapcraft.yaml (which pins
# the MongoDB tools/mongosh versions) are available; the downloaded bundle
# is extracted alongside it in the workspace root.
- uses: actions/checkout@v7
with:
ref: refs/tags/v${{ needs.prepare.outputs.version }}
path: src
- uses: actions/setup-node@v7
with:
node-version: ${{ env.NODE_VERSION }}
# Which Node.js this platform gets - and whether it is built at all.
#
# WeKan takes its Node.js from official nodejs.org, then
# unofficial-builds.nodejs.org, then wekan/node-patches
# (releases/resolve-node-source.sh is the one place that order lives).
# When NO source has one for this CPU the platform is simply NOT BUILT
# this release: every step below is gated on skip, and it comes back by
# itself the first run after a Node.js for it is published anywhere.
- name: Preflight - resolve this platform's Node.js
id: preflight
shell: bash
run: |
set -uo pipefail
out="$(bash src/releases/resolve-node-source.sh 'win-arm64' "$NODE_VERSION")" || true
if printf '%s\n' "$out" | grep -q '^node_found=true$'; then
printf '%s\n' "$out" | grep -E '^node_(full|from|url|kind|member|sha256)=' >> "$GITHUB_OUTPUT"
echo "skip=false" >> "$GITHUB_OUTPUT"
printf '%s\n' "$out" | grep -E '^node_(full|from|url)='
else
echo "::warning::win-arm64 is not built this time. No Node.js for it at nodejs.org, unofficial-builds.nodejs.org or wekan/node-patches; it returns by itself when one is published."
echo "skip=true" >> "$GITHUB_OUTPUT"
fi
- name: Install 7-zip
if: steps.preflight.outputs.skip != 'true'
run: choco install -y 7zip
- name: Download amd64 bundle
if: steps.preflight.outputs.skip != 'true'
uses: actions/download-artifact@v8
with:
name: bundle-amd64
- name: Fix bcrypt for Node.js 24
if: steps.preflight.outputs.skip != 'true'
shell: bash
run: |
7z x wekan-${VERSION}-amd64.zip
# Drop the Linux node + FerretDB binaries + MongoDB Database Tools + POSIX
# launcher inherited from the amd64 base bundle; the Windows node.exe,
# ferretdb.exe, *.exe tools and start-wekan.bat are added in later steps.
rm -f bundle/node bundle/ferretdb bundle/.ferretdb-default bundle/start-wekan.sh
rm -f bundle/bsondump bundle/mongodump bundle/mongoexport bundle/mongofiles \
bundle/mongoimport bundle/mongorestore bundle/mongostat bundle/mongotop
# Linux-only cpu-exec + qemu-user (#6458) make no sense on Windows.
rm -f bundle/cpu-exec bundle/qemu-x86_64
# Fix: bcrypt 5.0.1 (Meteor accounts-password) ships node-addon-api@3
# which fails to compile on Node.js 24. Replace with bcrypt 6.0.0.
BCRYPT_DIR="$(pwd)/bundle/programs/server/npm/node_modules/meteor/accounts-password/node_modules/bcrypt"
if [ -d "$BCRYPT_DIR" ]; then
rm -rf "$BCRYPT_DIR"
TMP=$(mktemp -d)
pushd "$TMP" > /dev/null
npm pack bcrypt@6.0.0
mkdir bcrypt && tar xzf bcrypt-*.tgz --strip-components=1 -C bcrypt
cd bcrypt && npm install --ignore-scripts && cd ..
cp -r bcrypt "$BCRYPT_DIR"
popd > /dev/null
rm -rf "$TMP"
fi
- name: Rebuild native modules for Windows
if: steps.preflight.outputs.skip != 'true'
shell: bash
run: |
cd bundle/programs/server
rm -rf node_modules
npm install
- name: Check the binaries the win-arm64 bundle needs exist
if: steps.preflight.outputs.skip != 'true'
# bash, not the Windows default shell: this is a bash script (`set -euo
# pipefail`, a bash script call). Without it PowerShell runs the body and
# dies on `set -euo pipefail` with "A parameter cannot be found that
# matches parameter name 'euo'".
shell: bash
run: |
set -euo pipefail
# This job checks the repo out into src/ (see the checkout step above),
# so the script lives at src/releases/, not the workspace root - the
# same path the start-wekan.bat copy below uses.
bash src/releases/require-binaries.sh 'win-arm64 bundle' \
'https://github.com/wekan/FerretDB/releases/latest/download/ferretdb-win-arm64.exe'
- name: Add MongoDB Database Tools to the bundle
if: steps.preflight.outputs.skip != 'true'
shell: bash
run: |
set -euo pipefail
# MongoDB Database Tools (Windows) built by wekan/mongo-tools-patches (pure Go),
# one <tool>-win-arm64.exe per tool from that repo's newest release — no
# mongodb.com dependency. No mongosh: WeKan no longer bundles the MongoDB
# Shell; scripted DB access uses the bundled Node.js 24 + `mongodb` driver.
# (The Windows launcher, start-wekan.bat, is added by the FerretDB embed
# step below from releases/ferretdb/start-wekan.bat.)
BASE="https://github.com/wekan/mongo-tools-patches/releases/latest/download"
for tool in bsondump mongodump mongoexport mongofiles mongoimport mongorestore mongostat mongotop; do
curl -fL --retry 5 --retry-delay 10 -o "bundle/${tool}.exe" "${BASE}/${tool}-win-arm64.exe"
done
echo "=== bundle contents ==="
ls -1 bundle/
- name: Embed Node.js, FerretDB (win-arm64) and launcher into the bundle
if: steps.preflight.outputs.skip != 'true'
shell: bash
# Make the Windows .zip self-contained: bundle node.exe (from the runner's
# win-arm64 Node 24), ferretdb.exe (downloaded per-arch from the newest
# wekan/FerretDB release) and start-wekan.bat. FerretDB embedding is
# tolerant: if the win-arm64 asset is missing the bundle stays MongoDB-only
# (start-wekan.bat then won't find ferretdb.exe).
run: |
# Bundled Node.js: download the pinned Node ${NODE_VERSION} win-arm64
# node.exe from nodejs.org and VERIFY it, rather than copying the
# runner's unchecksummed node. Exports NODE_FULL/NODE_SHA256 for
# provenance.
# Capture node_full/node_sha256 in THIS shell (provenance is recorded in
# the same step, and $GITHUB_ENV only reaches later steps); a failed
# download/verify stops the build here rather than at the later guard.
node_meta="$(bash src/releases/embed-verified-node.sh bundle/node.exe node-win-arm64.exe "$NODE_VERSION")" \
|| { echo "::error::Verified Node.js embed failed for win-arm64."; exit 1; }
eval "$node_meta"
# Bundled FerretDB (win-arm64): download this arch's binary and verify it
# against the .sha256sum wekan/FerretDB publishes beside it.
FERRET_URL="https://github.com/wekan/FerretDB/releases/latest/download/ferretdb-win-arm64.exe"
if curl -fSL --retry 5 --retry-delay 10 -o bundle/ferretdb.exe "$FERRET_URL"; then
echo "Embedded FerretDB win-arm64 -> bundle/ferretdb.exe"
if curl -fsSL "${FERRET_URL}.sha256sum" -o /tmp/ferretdb.sha256sum 2>/dev/null; then
FERRET_SHA="$(awk '{print $1; exit}' /tmp/ferretdb.sha256sum)"
GOT="$(sha256sum bundle/ferretdb.exe | cut -d' ' -f1)"
if [ "$GOT" != "$FERRET_SHA" ]; then
echo "::error::FerretDB win-arm64 does not match its published SHA256 (published $FERRET_SHA, got $GOT)."
exit 1
fi
echo "FerretDB SHA256 verified: $GOT"
echo "FERRET_SHA=$FERRET_SHA" >> "$GITHUB_ENV"
else
echo "::warning::wekan/FerretDB publishes no checksum for ferretdb-win-arm64.exe on this release, so it is unverified."
fi
else
rm -f bundle/ferretdb.exe
echo "No win-arm64 FerretDB asset in the release; Windows bundle stays MongoDB-only."
fi
# Self-contained Windows launcher (defaults to FerretDB SQLite).
cp src/releases/ferretdb/start-wekan.bat bundle/
# Where this bundle's binaries came from, for the release notes.
mkdir -p provenance
PROVENANCE_FILE=provenance/win-arm64.tsv bash src/releases/record-provenance.sh \
'win-arm64' 'Node.js' "${node_from:-}" "${node_full:-$NODE_VERSION}" \
"${node_url:-}" \
"${node_sha256:-}" || true
if [ -s bundle/ferretdb.exe ]; then
FERRET_TAG="$(bash src/releases/ferretdb-latest-tag.sh || true)"
PROVENANCE_FILE=provenance/win-arm64.tsv bash src/releases/record-provenance.sh \
'win-arm64' 'FerretDB' 'wekan/FerretDB' "${FERRET_TAG:-latest}" \
'https://github.com/wekan/FerretDB/releases/latest/download/ferretdb-win-arm64.exe' \
"${FERRET_SHA:-}" || true
fi
# Check what goes IN, before anything is archived. This is the honest place
# for it: whether the zip can hold a startable bundle is decided here, in a
# plain directory, with no archive-listing format in the way.
for want in main.js node.exe start-wekan.bat; do
if [ ! -s "bundle/$want" ]; then
echo "::error::bundle/$want is missing or empty, so the win-arm64 zip cannot start WeKan. The bundle comes from the build job; the lines above say what was copied in."
exit 1
fi
done
echo "bundle/ has main.js, node.exe and start-wekan.bat:"
ls -la bundle
- name: Create win-arm64 zip
if: steps.preflight.outputs.skip != 'true'
shell: cmd
run: 7z a wekan-%VERSION%-win-arm64.zip bundle
- name: Verify the win-arm64 zip
if: steps.preflight.outputs.skip != 'true'
shell: bash
run: |
# Same question as on the other platforms, asked in bash because the zip
# itself is made with 7-Zip under cmd: does this zip actually carry a
# startable bundle, or only a name that looks like one?
zip="wekan-${VERSION}-win-arm64.zip"
if [ ! -f "$zip" ]; then
echo "::error::$zip was not created - 7z failed above, or the bundle directory was missing."
exit 1
fi
# A checksum beside the bundle, so a download can be checked.
sha256sum "$zip" > "${zip}.sha256sum"
cat "${zip}.sha256sum"
bytes=$(wc -c < "$zip")
if [ "$bytes" -lt 10000000 ]; then
echo "::error::$zip is only $bytes bytes; a whole bundle is tens of megabytes. The bundle directory was empty or partial when it was zipped."
exit 1
fi
# Integrity: `7z t` reads every entry and fails on a truncated or corrupt
# archive. Together with the check on bundle/ before zipping, that is what
# actually decides whether this zip is startable.
if ! 7z t "$zip" > 7z-test.log 2>&1; then
echo "::error::$zip did not pass 7z t - the archive is corrupt or truncated."
tail -n 30 7z-test.log
exit 1
fi
echo "7z t: archive is intact."
# The listing is EVIDENCE, printed, not a hidden verdict. v10.48 failed the
# release because `grep` found neither "bundle\main.js" nor "bundle/main.js"
# in `7z l -ba` output that nothing ever printed, so a bad zip and a bad
# grep looked exactly alike. Now the listing shows itself, and a missing
# match is a WARNING: bundle/main.js was verified to exist before zipping
# and the archive passed its integrity test, so a zero count here says
# something about 7-Zip's output format, not about the bundle.
# Through a FILE, never a pipe. `cmd | head`/`cmd | grep -q` ends the
# reader early, the writer gets SIGPIPE, and with `set -o pipefail` (which
# GitHub's bash uses) the pipeline's status becomes 141 - so under `set -e`
# a MATCH fails the step. That is what "has no bundle/main.js" was in
# v10.48, and what exit code 141 was in v10.49: the file was there both
# times, and the listing below proves it (`bundle\main.js`, five lines in).
7z l -ba "$zip" > zip-listing.txt 2>/dev/null || true
entries="$(wc -l < zip-listing.txt)"
echo "7z l -ba listed $entries entries; the first five:"
head -5 zip-listing.txt || true
for want in main.js node.exe; do
n="$(grep -F -c -e "bundle\\$want" -e "bundle/$want" zip-listing.txt || true)"
echo " entries matching bundle/$want: $n"
if [ "${n:-0}" -eq 0 ]; then
echo "::warning::$zip listing shows no bundle/$want, but bundle/$want existed before zipping and the archive passed 7z t. Compare the five listing lines above with what is being searched for."
fi
done
echo "OK: $zip is $((bytes/1024/1024)) MiB, intact, and was built from a bundle that had main.js and node.exe."
- uses: actions/upload-artifact@v7
if: steps.preflight.outputs.skip != 'true'
with:
name: bundle-win-arm64
path: wekan-${{ needs.prepare.outputs.version }}-win-arm64.zip
retention-days: 1
- name: Upload win-arm64 provenance
if: steps.preflight.outputs.skip != 'true'
uses: actions/upload-artifact@v7
with:
name: provenance-win-arm64
path: provenance/
if-no-files-found: ignore
retention-days: 1
- name: Attach win-arm64 bundle to the GitHub Release
if: steps.preflight.outputs.skip != 'true'
shell: bash
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# The repo is checked out into src/, so the workspace root is not a git
# repository; set GH_REPO so `gh` targets wekan/wekan without relying on
# git remote detection (else: "fatal: not a git repository").
GH_REPO: ${{ github.repository }}
run: |
set -euo pipefail
asset="wekan-${VERSION}-win-arm64.zip"
if [ ! -f "$asset" ]; then
echo "::error::$asset does not exist, so there is nothing to attach. The step that builds it failed, or produced a different name."
exit 1
fi
# The checksum goes up with it, so a download can be checked. It is
# built beside the zip by the step above; older jobs that do not make
# one still upload cleanly.
up=("$asset")
[ -f "${asset}.sha256sum" ] && up+=("${asset}.sha256sum")
if ! gh release upload "v${VERSION}" "${up[@]}" --clobber; then
echo "::error::Could not attach $asset to release v${VERSION}: the release must exist first (the release job), and GITHUB_TOKEN must be allowed to write releases here."
exit 1
fi
# Confirm from the OTHER side. An upload that reports success but leaves no
# asset behind is the failure nobody notices until a download 404s.
gh release view "v${VERSION}" --json assets --jq '.assets[].name' > release-assets.txt
if ! grep -qxF "$(basename "$asset")" release-assets.txt; then
echo "::error::$asset is not listed in release v${VERSION} although the upload reported success. Re-run this job."
exit 1
fi
echo "OK: $(basename "$asset") is attached to release v${VERSION} ($(($(wc -c < "$asset")/1024/1024)) MiB)."
# Always, as the last step: the run summary then answers "what worked and what
# did not" for the whole release at a glance, instead of eighteen job logs. A
# step that failed has already printed an ::error:: saying why; this names the
# job it was in.
- name: Job result
if: always()
# bash explicitly: this same step runs on the Windows and macOS runners too,
# where the default shell is PowerShell / not necessarily this bash.
shell: bash
run: |
case "${{ job.status }}" in
success) mark='OK ' ;;
failure) mark='FAILED ' ;;
cancelled) mark='CANCELLED' ;;
*) mark='${{ job.status }}' ;;
esac
echo "$mark build-win-arm64"
echo "$mark build-win-arm64" >> "$GITHUB_STEP_SUMMARY"
if [ "${{ job.status }}" = "failure" ]; then
echo "::error::build-win-arm64 FAILED. The ::error:: line in this job's log, above, says which step and why."
fi
# Build win32 (32-bit Windows) bundle.
#
# BEST-EFFORT, like mac-x64 and the exotic Linux arches: nodejs.org has no
@@ -1573,7 +1940,7 @@ jobs:
"${node_url:-}" \
"${node_sha256:-}" || true
if [ -s bundle/ferretdb.exe ]; then
FERRET_TAG="$(bash src/releases/ferretdb-latest-tag.sh)"
FERRET_TAG="$(bash src/releases/ferretdb-latest-tag.sh || true)"
PROVENANCE_FILE=provenance/win32.tsv bash src/releases/record-provenance.sh \
'win32' 'FerretDB' 'wekan/FerretDB' "${FERRET_TAG:-latest}" \
'https://github.com/wekan/FerretDB/releases/latest/download/ferretdb-win32.exe' \
@@ -1818,7 +2185,7 @@ jobs:
"${node_url:-}" \
"${node_sha256:-}" || true
if [ -s bundle/ferretdb ]; then
FERRET_TAG="$(bash releases/ferretdb-latest-tag.sh)"
FERRET_TAG="$(bash releases/ferretdb-latest-tag.sh || true)"
PROVENANCE_FILE=provenance/mac-arm64.tsv bash releases/record-provenance.sh \
'mac-arm64' 'FerretDB' 'wekan/FerretDB' "${FERRET_TAG:-latest}" \
'https://github.com/wekan/FerretDB/releases/latest/download/ferretdb-mac-arm64' \
@@ -2071,7 +2438,7 @@ jobs:
"${node_url:-}" \
"${node_sha256:-}" || true
if [ -s bundle/ferretdb ]; then
FERRET_TAG="$(bash releases/ferretdb-latest-tag.sh)"
FERRET_TAG="$(bash releases/ferretdb-latest-tag.sh || true)"
PROVENANCE_FILE=provenance/mac-x64.tsv bash releases/record-provenance.sh \
'mac-x64' 'FerretDB' 'wekan/FerretDB' "${FERRET_TAG:-latest}" \
'https://github.com/wekan/FerretDB/releases/latest/download/ferretdb-mac-amd64' \
@@ -2255,6 +2622,18 @@ jobs:
node_arch: x86
ferretdb_arch: i386
optional: true
# ARMv6: Raspberry Pi 1 and Zero. It runs in a linux/arm/v6 container,
# takes wekan/node-patches' node-armv6 (nobody else publishes an ARMv6
# Node - nodejs.org dropped it after Node 11), and FerretDB and the
# MongoDB tools build a GOARM=6 armv6 of their own. Their armel is
# GOARM=5 and WOULD run on these boards, but in software floating
# point, so it is not used here.
- arch: armv6
platform: linux/arm/v6
image: debian:trixie
node_arch: armv6
ferretdb_arch: armv6
optional: true
- arch: armhf
platform: linux/arm/v7
image: debian:trixie
@@ -2436,7 +2815,7 @@ jobs:
else
echo "::warning::wekan/FerretDB publishes no checksum for ferretdb-${{ matrix.ferretdb_arch }} on this release, so it is unverified."
fi
FERRET_TAG="$(bash releases/ferretdb-latest-tag.sh)"
FERRET_TAG="$(bash releases/ferretdb-latest-tag.sh || true)"
bash releases/record-provenance.sh '${{ matrix.arch }}' 'FerretDB' \
'wekan/FerretDB' "${FERRET_TAG:-latest}" "$FERRET_URL" "$FERRET_SHA"
# Overwrite the inherited amd64 MongoDB Database Tools with this arch's ones.
@@ -2858,11 +3237,37 @@ jobs:
base="https://github.com/wekan/wekan/releases/download/v${VERSION}"
have() { curl -fsSL -o /dev/null -I --retry 3 --retry-delay 5 "$1"; }
# docker platform : the wekan bundle arch the Dockerfile downloads for it.
# linux/arm/v6 and linux/arm/v7 are BOTH TARGETARCH=arm and differ only in
# TARGETVARIANT, which is why the Dockerfile's arch case reads the variant.
req="linux/amd64:amd64 linux/arm64:arm64"
opt="linux/ppc64le:ppc64le linux/s390x:s390x linux/riscv64:riscv64 linux/386:i386 linux/arm/v7:armhf"
opt="linux/ppc64le:ppc64le linux/s390x:s390x linux/riscv64:riscv64 linux/386:i386 linux/arm/v6:armv6 linux/arm/v7:armhf"
# A bundle on the release is not enough: the BASE IMAGE has to publish the
# platform too, and for 32-bit ARM that is not a clean failure when it does
# not. containerd treats a LOWER arm variant as compatible, so a
# linux/arm/v6 request against a base that has arm/v5 and arm/v7 silently
# resolves to arm/v5 - Debian armel, SOFT-float - and the hard-float
# node-armv6 inside the armv6 bundle cannot run on that userland. Ask the
# base once, and treat a platform it does not publish exactly like a bundle
# that did not land. The base is read out of the Dockerfile so there is no
# second copy of its name here. arm64 is recorded as arm64/v8, which
# everyone writes as linux/arm64, so the implied /v8 is normalised away -
# the same normalisation the push-verify does below.
base_image="$(awk '/^FROM /{print $2; exit}' Dockerfile)"
base_plats="$(docker buildx imagetools inspect "$base_image" \
--format '{{range .Manifest.Manifests}}{{.Platform.OS}}/{{.Platform.Architecture}}{{if .Platform.Variant}}/{{.Platform.Variant}}{{end}} {{end}}' \
| sed 's#/v8 # #g')" || {
echo "::error::Cannot read the platform list of the base image ${base_image}."; exit 1; }
echo "Base image ${base_image} publishes: ${base_plats}"
base_has() { case " $base_plats " in *" $1 "*) return 0 ;; *) return 1 ;; esac; }
platforms=""; want=""; arches=""
for pair in $req; do
p="${pair%%:*}"; a="${pair#*:}"
if ! base_has "$p"; then
echo "::error::The base image ${base_image} does not publish $p, so the image cannot be built for it - and it is a CORE platform."
exit 1
fi
if have "${base}/wekan-${VERSION}-${a}.zip"; then
platforms="${platforms:+$platforms,}$p"; want="${want:+$want }$p"; arches="${arches:+$arches }$a"
else
@@ -2872,6 +3277,10 @@ jobs:
done
for pair in $opt; do
p="${pair%%:*}"; a="${pair#*:}"
if ! base_has "$p"; then
echo "::warning::$p is dropped from the image: the base image ${base_image} publishes no $p, and a request for it would resolve to a lower-variant base the ${a} bundle cannot run on. The ${a} bundle zip is unaffected."
continue
fi
if have "${base}/wekan-${VERSION}-${a}.zip"; then
platforms="${platforms},$p"; want="${want} $p"; arches="${arches} $a"
echo "including $p (wekan-${VERSION}-${a}.zip present)"
@@ -3651,11 +4060,42 @@ jobs:
fi
# base: core24 allows publishing to stable and candidate (core26 does not).
for f in "${snaps[@]}"; do
echo "Uploading $f to the Snap Store (stable,candidate,beta,edge)..."
if ! snapcraft upload --release=stable,candidate,beta,edge "$f"; then
echo "::error::The Snap Store refused the upload of $f. The snapcraft line above says which: 'is not a valid file' means the build produced nothing usable; 'Credentials could not be parsed' means SNAP_AUTH is not a readable exported login; 401/403 means it lacks the ACL for this snap name. The last two are fixed by re-exporting for all three names: snapcraft export-login --snaps wekan,wekan-ondra,wekan-gantt-gpl --acls package_access,package_push,package_release,package_update snap-auth.txt"
# RETRIED, because the upload can fail for a reason that has nothing
# to do with the snap. The store accepts the file, scans it, and can
# then answer:
# Status: error while processing
# Issues while processing snap:
# - binary_sha3_384: Error checking upload uniqueness.
# which is the store failing its OWN duplicate check on the digest
# it just computed - a server-side hiccup, not a bad snap. It hit
# riscv64, ppc64el and s390x in the same v10.78 run, each after a
# Launchpad build that had succeeded, so three good snaps were lost
# to it at once. Re-uploading the identical file is what fixes it.
up_attempts=3
uploaded=0
for u in $(seq 1 "$up_attempts"); do
echo "Uploading $f to the Snap Store (stable,candidate,beta,edge), attempt $u/$up_attempts..."
if snapcraft upload --release=stable,candidate,beta,edge "$f" 2>&1 | tee /tmp/snap-upload.log; then
uploaded=1
break
fi
# Only the store's own processing errors are worth retrying. A
# rejected file, or credentials the store will not accept, will be
# rejected exactly the same way three times - and retrying those
# only buries the message that says what to fix.
if grep -qiE 'Error checking upload uniqueness|error while processing|502 Bad Gateway|503 Service|504 Gateway|Timeout|Connection (reset|aborted)' /tmp/snap-upload.log; then
if [ "$u" -lt "$up_attempts" ]; then
echo "::warning::The Snap Store failed while PROCESSING $f (not a problem with the snap). Retrying in $((u * 30))s."
sleep $((u * 30))
continue
fi
echo "::error::The Snap Store failed while processing $f on every one of $up_attempts attempts. This is the store's own upload-uniqueness/processing check failing on a snap it accepted - the file itself built and downloaded fine, so re-running this job later usually publishes it unchanged. Nothing in this repository needs to change." >&2
exit 1
fi
echo "::error::The Snap Store refused the upload of $f. The snapcraft line above says which: 'is not a valid file' means the build produced nothing usable; 'Credentials could not be parsed' means SNAP_AUTH is not a readable exported login; 401/403 means it lacks the ACL for this snap name. The last two are fixed by re-exporting for all three names: snapcraft export-login --snaps wekan,wekan-ondra,wekan-gantt-gpl --acls package_access,package_push,package_release,package_update snap-auth.txt" >&2
exit 1
fi
done
[ "$uploaded" -eq 1 ] || exit 1
done
- name: Attach the ${{ matrix.arch }} snap to the GitHub Release
@@ -4143,6 +4583,7 @@ jobs:
- build-amd64
- build-arm64
- build-win64
- build-win-arm64
- build-win32
- build-mac-arm64
- build-mac-x64
+110 -19
View File
@@ -2,7 +2,35 @@
Codex reads this file at the repo root before doing work here. Follow it.
## First: are you the maintainer or a contributor?
## First: who maintains this, and who is committing?
**WeKan, the `wekan/` repositories cloned under `.tools/`, and
[Secretchronicles/TSC](https://github.com/Secretchronicles/TSC) are all maintained by
Lauri Ojansivu (xet7) `<x@xet7.org>`** — [wekan/wekan](https://github.com/wekan/wekan),
[wekan/FerretDB](https://github.com/wekan/FerretDB),
[wekan/node-patches](https://github.com/wekan/node-patches),
[wekan/mongo-tools-patches](https://github.com/wekan/mongo-tools-patches) and TSC,
which is under the **Secretchronicles** organisation rather than **wekan** and is his
all the same — his GitHub profile, [xet7](https://github.com/xet7), says exactly that:
*"WeKan and TSC maintainer"*. Work done on the maintainer's behalf is committed as
**`Lauri Ojansivu <x@xet7.org>`** — that author, in every one of those repositories,
every time. Two rules follow from it and neither has an exception:
- **Never attribute a commit to an AI.** No `Co-Authored-By:` trailer, no "Generated
with", no assistant or model name — not in the commit message, not in a pull-request
body, not in the CHANGELOG. [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) is where this
comes from: *"For pull requests, mention only those participants that are
**human**."* A `Thanks to ... and xet7 !` line credits people — the issue reporter
and xet7 — never a tool.
- **If the git identity is missing or wrong in one of these checkouts, set it; do not
commit under something else.** The `.tools/` clones are made by `build.sh` inside
this checkout and can come up with no `user.name`/`user.email` of their own, which
would silently author a commit as whatever the machine's default is:
```
git -C .tools/<repo> config user.name 'Lauri Ojansivu'
git -C .tools/<repo> config user.email 'x@xet7.org'
```
Check the current git identity before committing or releasing:
@@ -10,16 +38,25 @@ Check the current git identity before committing or releasing:
git config user.name && git config user.email
```
- **Maintainer mode** — ONLY when the identity is exactly
`Lauri Ojansivu <x@xet7.org>` (name `Lauri Ojansivu`, email `x@xet7.org`). Then, and
only then: commit **directly to the current branch** as `Lauri Ojansivu <x@xet7.org>`
with no AI trailer and no pull request, and the **publishing / release steps** below
are available.
- **Contributor mode** — any other git identity. Then: do **not** commit directly to
the branch and do **not** run any release/publishing step. Make changes on a branch
and open a **pull request** for the maintainer to review. The "commit as Lauri
Ojansivu", "commit directly", and all release instructions below are **maintainer-only
and do not apply to you**.
- **Maintainer mode** — the identity is `Lauri Ojansivu <x@xet7.org>` (name
`Lauri Ojansivu`, email `x@xet7.org`), or it is unset in a checkout of one of the
repositories above, which means it is to be SET to that as above rather than worked
around. Then: commit **directly to the current branch** as
`Lauri Ojansivu <x@xet7.org>` with no AI trailer and no pull request, and the
**publishing / release steps** below are available.
- **Contributor mode** — the identity is somebody ELSE, in a fork or a clone of your
own. Then: do **not** commit directly to the branch and do **not** run any
release/publishing step. Make changes on a branch and open a **pull request** for
the maintainer to review, and keep that pull request free of AI attribution too.
The "commit as Lauri Ojansivu", "commit directly", and all release instructions
below are **maintainer-only and do not apply to you**.
Maintainer mode covers TSC as well: commit directly to its `devel` branch, no pull
request, same author and no AI attribution. What it does NOT bring along is WeKan's
house style — TSC keeps its own **GNU ChangeLog** `CHANGELOG` and its own release
process, because a project is read on its own terms (see the CHANGELOG section below).
The one repository under `.tools/` that is somebody else's is `sandstorm-io/sandstorm`,
cloned for reference only.
Everything below marked as maintainer-specific (committing directly, the exact commit
author, and the entire "Making a release" / publishing flow) applies only in maintainer
@@ -121,21 +158,75 @@ pushed to Transifex as if it were human.
"Co-Authored-By" or any other AI trailer, directly to the `main` branch of WeKan and
the `main-v1` branch of the FerretDB fork. **Do not make pull requests.** (Contributors
do the opposite: work on a branch and open a pull request — see the top section.)
- Lauri Ojansivu (xet7) maintains WeKan (https://wekan.fi) and the FerretDB v1 fork.
This is the same rule as the top section, restated where the release work is: one
author, `Lauri Ojansivu <x@xet7.org>`, and no AI attribution anywhere.
- Lauri Ojansivu (xet7) maintains WeKan (https://wekan.fi), the FerretDB v1 fork, and
the two patch repositories under `.tools/` — node-patches and mongo-tools-patches.
- Directory structure:
- `wekan` — this repo (https://github.com/wekan/wekan); see
`docs/DeveloperDocs/Directory-Structure.md`; `CHANGELOG.md` at root.
- `../w/wekan.fi` — the WeKan website.
- `FerretDB` subdirectory (when present) — https://github.com/wekan/FerretDB, its own
`CHANGELOG.md`. FerretDB `.go` files must contain **no** application-specific names
(say "the client" / "a Meteor 3 driver" / a bare `#NNNN`); its `CHANGELOG.md` may
use `wekan/wekan#NNNN`.
- `sandstorm` subdirectory (when present) — https://github.com/sandstorm-io/sandstorm.
- `.tools/` — everything that is NOT part of this repository but is needed to
build, test and release it, in ONE directory that `.gitignore` and
`.meteorignore` already exclude (each used to need its own ignore entry at
the repo root), so nothing in it can reach a commit or a Meteor rebuild. Two
different kinds of thing live there, and the difference matters:
**Companion git repositories.** Separate repositories with their own history,
branches, changelog and release flow — a commit here is never a commit there.
`build.sh`'s `ensure_tool_repo` clones one on demand (SSH first, HTTPS
second), so a fresh checkout needs no manual setup:
| Path | Repository | Branch | What it is |
| --- | --- | --- | --- |
| `.tools/FerretDB` | wekan/FerretDB | `main-v1` | the FerretDB v1 fork WeKan ships as its default database |
| `.tools/node-patches` | wekan/node-patches | `main` | patches to upstream Node.js; builds the `node-<platform>` binaries the bundles, the Docker image and the snap embed |
| `.tools/mongo-tools-patches` | wekan/mongo-tools-patches | `main` | patches to the MongoDB Database Tools; builds `<tool>-<arch>` |
| `.tools/TSC` | Secretchronicles/TSC | `devel` | the game xet7 also maintains — same author and maintainer mode, its own GNU ChangeLog and release process |
| `.tools/sandstorm` | sandstorm-io/sandstorm | — | upstream Sandstorm, when present — somebody else's project, cloned for reference |
**Unpacked toolchains and caches.** Downloads, not repositories — put there by
the sandbox instructions in `docs/Security/Sandboxes/vscode/README.md`, deleted
and re-fetched freely, never committed anywhere:
`node-v<version>-linux-<arch>/` (the Node.js the test suites are run with),
`go/` with `gopath/`, `gomodcache/` and `gocache/` (FerretDB's Go builds),
`.meteor/` when `HOME` is pointed at `.tools`, and the `TSC*` AppImage.
- **Do NOT add a `CLAUDE.md` or an `AGENTS.md` to any repository under
`.tools/`.** node-patches and mongo-tools-patches each had a pair and they were
REMOVED on purpose: the rules are the same for every one of these repositories,
and a second copy of a rule drifts from the first. THIS file, and its `AGENTS.md`
twin beside it, are where they live for all of them. Something true of only one
of those repositories goes in that repository's own `README.md` or `docs/`,
never in a new instruction file — and if you find one there, remove it rather
than updating it.
- `.tools/FerretDB` specifics — FerretDB `.go` files must contain **no**
application-specific names (say "the client" / "a Meteor 3 driver" / a bare
`#NNNN`); its `CHANGELOG.md` may use `wekan/wekan#NNNN`.
### CHANGELOG
- **Every repository writes its changelog in the format that repository's own file
already uses.** Open its changelog, read the entries above the place you are
adding one, and match them — never import another project's shape into it. The
five that come up here:
| Repository | File | Format |
| --- | --- | --- |
| `wekan/wekan` | `CHANGELOG.md` | the WeKan format this section describes: `# Platforms`, `# TODO Later`, then `# v<MAJOR>.<MINOR> YYYY-MM-DD WeKan ® release` sections of `<details>` entries whose `<summary>` links the commit |
| `wekan/node-patches` | `CHANGELOG.md` | the same WeKan format, with `# Upcoming node-patches release` |
| `wekan/mongo-tools-patches` | `CHANGELOG.md` | the same WeKan format, with `# Upcoming mongo-tools-patches release` |
| `wekan/FerretDB` | `CHANGELOG.md` | **upstream FerretDB's** format, not WeKan's: `## [v1.48.0](tag URL) (YYYY-MM-DD)` and `### New Features 🎉` / `### Fixed 🐛` / `### Other Changes 🤖` bullets ending `by @xet7. Thanks to xet7.` |
| `Secretchronicles/TSC` | `CHANGELOG` (no extension) | **GNU ChangeLog** format: a `YYYY-MM-DD Name <email>` header line, then TAB-indented `* Version …` / `* Fix: …` / `* Misc: …` entries, wrapped and continued with further tabs, each ending `(by Name)` |
The reason is the reader, not consistency for its own sake: a FerretDB release is
read beside upstream FerretDB's releases, and a TSC entry beside a decade of GNU
ChangeLog entries. A WeKan-shaped `<details>` block in either would be the odd one
out and would break the tooling that parses them. When this file and the file being
edited disagree, **the file being edited wins** — and everything below in this
section is about the WeKan format specifically.
- During development, add entries under a new `# Upcoming WeKan ® release` section above
the newest release (FerretDB uses `## Upcoming FerretDB release`). Do **not** hand-edit
the newest release (FerretDB uses `## Upcoming FerretDB release`; the patch repos use
`# Upcoming <repo> release`). Do **not** hand-edit
`package.json` or any other version reference — the release workflow bumps those.
- **The file's shape, top to bottom** — keep it exactly as it is now:
1. `# Platforms` — the line `Newest WeKan at these platforms:` and the Install /
@@ -342,7 +433,7 @@ All publishing / release steps below are maintainer-only. Contributors never run
version reference, then the release jobs tag `v<new>` and publish the GitHub Release).
An explicit `oldversion newversion` pair still overrides. Adding entries under Upcoming
is the only hand step.
- FerretDB: run `./build.sh release-ferretdb` from the `FerretDB` subdirectory (no
- FerretDB: run `./build.sh release-ferretdb` from `.tools/FerretDB` (no
version). It renames `## Upcoming FerretDB release` to the next version with the
correct git-tag link, commits + tags + pushes, then triggers `release-all.yml` (which
in turn triggers `docker.yml` for the multi-arch image). It refuses to re-release an
+745 -1
View File
@@ -241,6 +241,18 @@ webhook — card title/description edits ALREADY reach the global webhook via
from #3619/#5482; a single consolidated `act-editCard` action needs a decision
on which fields count and whether it supplements or replaces the existing
per-field events, to avoid duplicate webhook deliveries),
[#6580](https://github.com/wekan/wekan/issues/6580) (CHANGELOG.md is 43,748
lines and 2.02 MB, over the size at which GitHub refuses to render it — its
Blame tab answers *"we can't show files that are this big"* and the file view
truncates. Splitting it by year was tried and abandoned: git records no move,
so a plain `git blame` on a per-year file credits every line to the commit that
split it, and only `git blame -C` reaches the real history — which editors do
not pass by default. That traded working local blame on eleven years of entries
for a smaller file, and local blame is worth more. Reverting a split does not
undo it either: the restored lines blame to the revert, so the only clean way
back is to not land it. Any fix needs a way to shrink the file that keeps `git
blame` working with no flag — or a decision that the trade is acceptable after
all),
.
</details>
@@ -264,6 +276,736 @@ browser build to verify).
</details>
# v10.80 2026-08-10 WeKan ® release
**In short:** the **Admin Panel**, in the two panes v10.79 had just changed.
**Version** is one table again rather than five: five tables sized their columns
independently, so the values started at a different x in every category. The
categories are rows inside one table now - bold, spanning both columns - over
two equal 50% columns. **Problems / Filesystem integrity** drew a blank page:
the one piece of its wiring that was missing was a template helper, and Blaze
reads an undefined helper as false rather than complaining. The binaries below
are v10.79's: nothing here rebuilds them.
| Platform | Binary | From | Version | SHA256 |
| --- | --- | --- | --- | --- |
| amd64 | Node.js | [nodejs.org](https://nodejs.org/dist/v24.19.0/node-v24.19.0-linux-x64.tar.xz) | v24.19.0 | `14b342e71204f811bde6153be8e04b62aef63c236fef92b55f9c83154b409647` |
| amd64 | FerretDB | [wekan/FerretDB](https://github.com/wekan/FerretDB/releases/download/v1.48.0/ferretdb-amd64) | v1.48.0 | `2737687fd29a8a761cd960e45f300b68cf7b4a87d50c4cc5280bcbd42b6aa163` |
| arm64 | Node.js | [nodejs.org](https://nodejs.org/dist/v24.19.0/node-v24.19.0-linux-arm64.tar.xz) | v24.19.0 | `01443c1e1a29e531ccad5a46fefa6df490d2189c49f7955904aecdbb0fe86fdc` |
| arm64 | FerretDB | [wekan/FerretDB](https://github.com/wekan/FerretDB/releases/download/v1.48.0/ferretdb-arm64) | v1.48.0 | `5ae705dd49515a4ecd4e295c3b9aa4f3b454fad78613ec60fb99316bd7c34e3f` |
| loong64 | Node.js | [unofficial-builds.nodejs.org](https://unofficial-builds.nodejs.org/download/release/v24.19.0/node-v24.19.0-linux-loong64.tar.xz) | v24.19.0 | `c24f224726f2d785bd18a1fd09f5e6d1fecf0269928451a60c5da9eac8e92e68` |
| loong64 | FerretDB | [wekan/FerretDB](https://github.com/wekan/FerretDB/releases/download/v1.48.0/ferretdb-loong64) | v1.48.0 | `06ec86263455a7b598d22a87df0e044ea73ab5a3b72e96ad12ebed03c1374ac2` |
| mac-arm64 | Node.js | [nodejs.org](https://nodejs.org/dist/v24.19.0/node-v24.19.0-darwin-arm64.tar.xz) | v24.19.0 | `3f1cf157479c1480352083105e13faf9d008ede98e7e157746b6df940d197b94` |
| mac-arm64 | FerretDB | [wekan/FerretDB](https://github.com/wekan/FerretDB/releases/download/v1.48.0/ferretdb-mac-arm64) | v1.48.0 | `9b15f4c10e473cd0a2c4feb4cb43e18042bd60c7035ec66cab3cfbe13edaabab` |
| mac-x64 | Node.js | [nodejs.org](https://nodejs.org/dist/v24.19.0/node-v24.19.0-darwin-x64.tar.xz) | v24.19.0 | `d35e95230f46f6f0751df497c56622c6735e05d5e1fb1630996a005b9d328fe4` |
| mac-x64 | FerretDB | [wekan/FerretDB](https://github.com/wekan/FerretDB/releases/download/v1.48.0/ferretdb-mac-amd64) | v1.48.0 | `4e188246dfa33bccef4cdd86701bc498b037cb3e91f579ff0dccb93aa0ef03ad` |
| ppc64le | Node.js | [nodejs.org](https://nodejs.org/dist/v24.19.0/node-v24.19.0-linux-ppc64le.tar.xz) | v24.19.0 | `c510c6ce12f07010f771e6edb22a3fe23f4f2e6f40b1ffd4941aed0646a0d8b3` |
| ppc64le | FerretDB | [wekan/FerretDB](https://github.com/wekan/FerretDB/releases/download/v1.48.0/ferretdb-ppc64le) | v1.48.0 | `0400cd6dfc3d10d987a0fe80d75baa86c03c19170770fa2e602c92d558c3cfa6` |
| riscv64 | Node.js | [unofficial-builds.nodejs.org](https://unofficial-builds.nodejs.org/download/release/v24.19.0/node-v24.19.0-linux-riscv64.tar.xz) | v24.19.0 | `cd1f14af2812148002f58b58a5f9af512a50e3b8e8c148e0db44019dcb68edfd` |
| riscv64 | FerretDB | [wekan/FerretDB](https://github.com/wekan/FerretDB/releases/download/v1.48.0/ferretdb-riscv64) | v1.48.0 | `d37c35af988670b9ed182b8c5966c06a06362f6c6ace6aebd93ccdfa32c9a26b` |
| s390x | Node.js | [nodejs.org](https://nodejs.org/dist/v24.19.0/node-v24.19.0-linux-s390x.tar.xz) | v24.19.0 | `a4792e65962ffa0af42627aacf1122a60c3c88dbf4e4184f06820d66f9da8ba4` |
| s390x | FerretDB | [wekan/FerretDB](https://github.com/wekan/FerretDB/releases/download/v1.48.0/ferretdb-s390x) | v1.48.0 | `6c7d61fbb8c79b2e8733be8f71910f710e8c5cd25208c451bdc513c8313b0340` |
| win64 | Node.js | [nodejs.org](https://nodejs.org/dist/v24.19.0/node-v24.19.0-win-x64.zip) | v24.19.0 | `57f71ab3652e797d84acddc79c81cc9ff1c6ddb2a1974cdb83f00fee9bff4c73` |
| win64 | FerretDB | [wekan/FerretDB](https://github.com/wekan/FerretDB/releases/download/v1.48.0/ferretdb-win64.exe) | v1.48.0 | `ea57e1bcd153b51d2065ab01515b21ec05d8f615444c15603ab8158b8a661dd2` |
This release reorganises the Admin Panel:
**Admin Panel / Settings** - the Version pane, and how it lays itself out.
<details>
<summary><a href="https://github.com/wekan/wekan/commit/aed26c677">Version is one table with combined category rows, over two 50% columns</a>. Thanks to xet7.</summary>
The pane arrived at v10.79 as five tables, one per category. Five tables size
their columns independently: "WeKan ® Version" made the first one's label column
wide and "OS Type" made the next one's narrow, so the values started at a
different x in every group and the pane read as five unrelated things.
One table now, and each category is a **row** in it — a `th` with `colspan=2`,
bold and start-aligned, so it says what the rows under it are about instead of
being a label with an empty cell beside it. A `colgroup` of two 50% columns plus
`table-layout: fixed` puts every label and every value in the same place down
the whole pane; the 240px header cap the other admin tables carry is undone for
this one, since its width is now stated outright and the cap would fight it.
The category title keeps the table's own font size deliberately: at the pane
title's size, five of them would read as five pane titles and "Version" would
be lost among them.
Two of the repository's own guards caught mistakes on the way, which is what
they are for. The jade compile check refused `th(colspan=2)` — the Meteor jade
dialect wants the value quoted, and an unquoted one is a build failure rather
than a rendering difference — and the RTL check refused `text-align: left`,
because the label column is on the RIGHT in Arabic and Hebrew, so it is
`start`.
</details>
and fixes the following bugs:
**Admin Panel / Problems** - a pane that drew nothing, and said nothing about
it.
<details>
<summary><a href="https://github.com/wekan/wekan/commit/01c36852d">Problems / Filesystem integrity showed a blank page</a>. Thanks to xet7.</summary>
The pane drew its title and then empty space, while Summary went on reporting
*"7 new problems"* for it.
Everything about it looked right, which is why it survived: the menu has a
`report-integrity` entry, clicking it is handled, the handler sets
`tmpl.showIntegrity`, and the template has `else if showIntegrity.get` with an
integrity event stream under it. The missing piece was the **helper**.
`showIntegrity()` was never added beside `showDatabase()` and the eight others,
and in Blaze **an undefined helper is not an error — it is falsy**. So the
branch never ran, the page was blank, and nothing anywhere said why.
The guard added with it is the class rather than this one pane: every
`show*.get` branch in a settings template must have a helper of that name in
that template's own `.js`, and a `ReactiveVar` behind it. The templates are
FOUND rather than listed, so a pane added later is covered without editing the
test.
</details>
**The snap** - what it does when it cannot read the database it was upgraded
onto.
<details>
<summary><a href="https://github.com/wekan/wekan/commit/562fa0271">A database this snap cannot read stops and says so, instead of serving 502 forever</a>. Thanks to Philippe-Bentegeac, JDeepix, imlit and xet7.</summary>
A snap upgraded onto a database left by a **MongoDB 4.x or 5.x** snap served 502
Bad Gateway indefinitely, with the reason only in `snap logs`:
```
This version of MongoDB is too recent to start up on the existing data files.
Try MongoDB 4.2 or earlier.
```
The snap carries **two** readers — mongod 7, the server it runs, and the MongoDB
3.2 tools for a 6.09-era database — and nothing in between, so 4.x data opens in
neither. What the code did then is the one thing that cannot work: the migration
found that neither reader could open it and handed back to `mongodb-control`,
which started mongod, which failed the same way, which re-ran the migration —
three times by its own counter — and then exited for snapd to restart. Nothing
in that loop can succeed, because reading those files needs a binary the snap
does not have.
**It stops now.** The migration tells "no reader for this vintage" from
"unreadable or corrupt" by mongod's own words, records the version mongod named
as still able to read the data, pauses auto-migration and exits **0** — zero,
because snapd restarts a failing service forever and no restart can help here.
`mongodb-control` will not start a mongod it knows cannot start, and WeKan
serves an explanatory page on the web port, both at startup and from inside the
database wait loop, so an instance already waiting switches over without a
restart.
The page names the MongoDB version that can still read the files and gives the
two ways forward — go back to the revision that worked, or dump with a MongoDB
that can read it and restore into this version — says plainly that **nothing was
changed** and that attachments and avatars are files on disk, and drops the
auto-refresh and the spinner the other two maintenance pages carry: this is a
stop, not a wait, and the page should not promise that something is happening.
Nothing is deleted or modified on this path: the source data is exactly as it
was, the marker file is the only thing written, and removing it lets the snap
try again. The snap documentation gains the section an admin searching for that
mongod line will find, with the commands.
The test covers the wiring in all three scripts and then RUNS the page — it is
standalone Node with no dependencies — to check what an admin actually sees:
503, the version, "untouched", both remedies, no refresh, no spinner.
</details>
<details>
<summary><a href="https://github.com/wekan/wekan/commit/71ba0c2dc">A third MongoDB reader, so a 4.x database migrates instead of stopping</a>. Thanks to Philippe-Bentegeac, JDeepix, imlit and xet7.</summary>
The entry above stopped the crash loop and explained it. This removes the reason
for it in the case that was actually reported.
A MongoDB server only starts on data whose `featureCompatibilityVersion` is at
most one major behind it, so what the snap can READ is decided by which servers
it carries: mongod 7 (FCV 6.0, 7.0) and the MongoDB 3.2 tools (3.2). Everything
in between was unreadable — and the WeKan snap has shipped 3.6, 4.0, 4.2, 4.4
and 5.0 over the years. The reported error names the gap exactly: *"Try
MongoDB 4.2 or earlier"*, which is FCV 4.0.
**mongod 4.2 is now bundled as a third reader**, used only to read the old data
during a migration and never as the running database. It opens FCV 4.0 and 4.2,
and the modern importer reads it with the bundled driver, which supports servers
from 4.2 up — the same importer that reads a 6/7 source, not a second copy of
it. The probes run newest-first: 7, then 4.2, then the 3.2 tools, then the page.
**amd64 and arm64 only.** MongoDB publishes no 4.2 for the others, and they have
been FerretDB from their first boot, so there is nothing there to migrate from.
**It carries its own OpenSSL 1.1.** The 4.2 build links `libssl.so.1.1` and
`libcrypto.so.1.1`, and core24 is Ubuntu 24.04, which ships OpenSSL 3 — without
them the binary does not even load. Both come from one Debian `libssl1.1`
package, staged beside the binary and put on `LD_LIBRARY_PATH` exactly as the
3.2 tools already are, with the filename resolved by listing the pool rather
than pinned, because point releases roll and a pinned name 404s the day they
do.
Optional by design: every failure in that part — download, checksum, OpenSSL, or
the binary not running — ends it with a message and no binary, and the migration
simply does not find one. A release is never failed over a migration aid.
Verified as far as a machine without a snap allows: mongod 4.2.25 aarch64 was
downloaded, staged with the Debian libssl1.1 and RUN — *"db version v4.2.25,
OpenSSL version: OpenSSL 1.1.1w"* — then started on a dbpath, forked and
listened on a port. That is the whole mechanism, on a 2026 system. The build
repeats the check and unstages the binary if it fails.
Still unreadable, and still answered by the page rather than a migration: 3.4,
3.6, 4.4 and 5.0. Bundling mongod 5.0 beside this one would close 4.4 and 5.0
the same way, at the same cost in size.
</details>
and improves the translations:
**Translations** - the new strings, and the languages that keep the English
placeholder.
<details>
<summary><a href="https://github.com/wekan/wekan/commit/132a64484">The Version pane's new strings, translated into 113 languages</a>. Thanks to xet7.</summary>
The pane's five category labels and the packaging row arrived in English only,
so every other language showed them in English. Three of the six needed
translating at all: **Platform**, **package** ("Package") and **OS**. `Database`
was already translated in 131 languages — the key existed before and this
revived it — and **Meteor** and **Node** are product names that stay as they
are in every language, which is also why the filler ignores a value equal to the
English source.
Translated directly, with no external service, using each language's own
existing strings as the reference. Its `OS_Type` and `OS_Platform` show the
form that language's translators use — *"Typ des Betriebssystems"*, *"Tipo
SO"*, *"Тип ОС"*, *"Käyttöjärjestelmän tyyppi"* — so OS is `Betriebssystem` in
German, `SO` in Italian and Portuguese, `ОС` in Russian and
`Käyttöjärjestelmä` in Finnish, rather than one spelling imposed on all of them.
Two files were deliberately NOT copied from: Greek's `OS_Type` and `OS_Platform`
hold Italian, and Korean's hold Japanese. Propagating that would have spread
somebody else's mistake into three more strings, so those two got proper Greek
and Korean instead.
Applied through `fill-translations.mjs --apply`, which writes **only** into a
placeholder, so no human translation could be overwritten even by accident — and
the diff shows it: 292 changed lines across 106 files, every one of them
`Platform`, `package` or `OS`. Key order and indentation are unchanged, every
file still parses, and `verify-human-preference.mjs` passes 10/10.
**40 files keep the English placeholder on purpose** — ace, ary, br, gu-IN, ig,
km, mn, oc, or_IN, pa, tk_TM, tlh, ug, ve, vl-SS, vo, wa, wo, xh, yi, yo, zgh,
zu and the `en-*` variants, which are English by design. A placeholder that
says so is better than a translation nobody can stand behind, and Transifex can
still replace any of them with a human one: nothing here is pushed there.
</details>
Thanks to above GitHub users for their contributions and translators for their
translations.
# v10.79 2026-08-10 WeKan ® release
**In short:** two **new platforms** and the **snap** jobs. WeKan now builds a
**win-arm64** bundle - Windows on ARM - which needed no new work anywhere else,
because nodejs.org, FerretDB and the MongoDB tools all publish that
architecture already and nothing here had asked for it. **armv6** - Raspberry
Pi 1 and Zero - was the opposite: nobody publishes a Node.js for it any more,
so **wekan/node-patches** gained an armv6 target, and FerretDB and the MongoDB
tools gained `GOARM=6` ones beside their armhf builds. It ships as a bundle zip
and **no snap**, because the Snap Store has no armv6 architecture at all; the
**Docker** image is wired for it too, but stays gated until a base image
publishes `linux/arm/v6` — Debian has no ARMv6 port, and a request for one
silently resolves to soft-float armel rather than failing. (armv5
and armel still cannot be added at all: V8's accepted `--arm-arch` list stops at
armv6, so there is no Node.js to build.) On the snap
side, one thing had been quietly failing for months: **armhf** asked Caddy for
a `linux_armhf` archive that has never existed - Caddy is built by Go and its
assets carry Go's architecture names -
and **riscv64**, **ppc64el** and **s390x** each built a perfectly good snap that
the Snap Store then refused while processing it, with an error about its own
duplicate check; the upload is retried now, and the message no longer blames
credentials. Beside that, the **amd64** bundle had never recorded where its
Node.js and FerretDB came from - not because the directory was wrong, which was
last release's fix, but because the scripts themselves were never found, and the
`|| true` meant for release notes swallowed the error every run. Below that, the
**CPU platforms** of the image and of the snap now have a page each, and the
FerretDB v1 page lists every architecture its binary is built for. The binaries
in the table below are v10.78's: nothing here rebuilds them.
| Platform | Binary | From | Version | SHA256 |
| --- | --- | --- | --- | --- |
| amd64 | Node.js | [nodejs.org](https://nodejs.org/dist/v24.19.0/node-v24.19.0-linux-x64.tar.xz) | v24.19.0 | `14b342e71204f811bde6153be8e04b62aef63c236fef92b55f9c83154b409647` |
| amd64 | FerretDB | [wekan/FerretDB](https://github.com/wekan/FerretDB/releases/download/v1.48.0/ferretdb-amd64) | v1.48.0 | `2737687fd29a8a761cd960e45f300b68cf7b4a87d50c4cc5280bcbd42b6aa163` |
| arm64 | Node.js | [nodejs.org](https://nodejs.org/dist/v24.19.0/node-v24.19.0-linux-arm64.tar.xz) | v24.19.0 | `01443c1e1a29e531ccad5a46fefa6df490d2189c49f7955904aecdbb0fe86fdc` |
| arm64 | FerretDB | [wekan/FerretDB](https://github.com/wekan/FerretDB/releases/download/v1.48.0/ferretdb-arm64) | v1.48.0 | `5ae705dd49515a4ecd4e295c3b9aa4f3b454fad78613ec60fb99316bd7c34e3f` |
| loong64 | Node.js | [unofficial-builds.nodejs.org](https://unofficial-builds.nodejs.org/download/release/v24.19.0/node-v24.19.0-linux-loong64.tar.xz) | v24.19.0 | `c24f224726f2d785bd18a1fd09f5e6d1fecf0269928451a60c5da9eac8e92e68` |
| loong64 | FerretDB | [wekan/FerretDB](https://github.com/wekan/FerretDB/releases/download/v1.48.0/ferretdb-loong64) | v1.48.0 | `06ec86263455a7b598d22a87df0e044ea73ab5a3b72e96ad12ebed03c1374ac2` |
| mac-arm64 | Node.js | [nodejs.org](https://nodejs.org/dist/v24.19.0/node-v24.19.0-darwin-arm64.tar.xz) | v24.19.0 | `3f1cf157479c1480352083105e13faf9d008ede98e7e157746b6df940d197b94` |
| mac-arm64 | FerretDB | [wekan/FerretDB](https://github.com/wekan/FerretDB/releases/download/v1.48.0/ferretdb-mac-arm64) | v1.48.0 | `9b15f4c10e473cd0a2c4feb4cb43e18042bd60c7035ec66cab3cfbe13edaabab` |
| mac-x64 | Node.js | [nodejs.org](https://nodejs.org/dist/v24.19.0/node-v24.19.0-darwin-x64.tar.xz) | v24.19.0 | `d35e95230f46f6f0751df497c56622c6735e05d5e1fb1630996a005b9d328fe4` |
| mac-x64 | FerretDB | [wekan/FerretDB](https://github.com/wekan/FerretDB/releases/download/v1.48.0/ferretdb-mac-amd64) | v1.48.0 | `4e188246dfa33bccef4cdd86701bc498b037cb3e91f579ff0dccb93aa0ef03ad` |
| ppc64le | Node.js | [nodejs.org](https://nodejs.org/dist/v24.19.0/node-v24.19.0-linux-ppc64le.tar.xz) | v24.19.0 | `c510c6ce12f07010f771e6edb22a3fe23f4f2e6f40b1ffd4941aed0646a0d8b3` |
| ppc64le | FerretDB | [wekan/FerretDB](https://github.com/wekan/FerretDB/releases/download/v1.48.0/ferretdb-ppc64le) | v1.48.0 | `0400cd6dfc3d10d987a0fe80d75baa86c03c19170770fa2e602c92d558c3cfa6` |
| riscv64 | Node.js | [unofficial-builds.nodejs.org](https://unofficial-builds.nodejs.org/download/release/v24.19.0/node-v24.19.0-linux-riscv64.tar.xz) | v24.19.0 | `cd1f14af2812148002f58b58a5f9af512a50e3b8e8c148e0db44019dcb68edfd` |
| riscv64 | FerretDB | [wekan/FerretDB](https://github.com/wekan/FerretDB/releases/download/v1.48.0/ferretdb-riscv64) | v1.48.0 | `d37c35af988670b9ed182b8c5966c06a06362f6c6ace6aebd93ccdfa32c9a26b` |
| s390x | Node.js | [nodejs.org](https://nodejs.org/dist/v24.19.0/node-v24.19.0-linux-s390x.tar.xz) | v24.19.0 | `a4792e65962ffa0af42627aacf1122a60c3c88dbf4e4184f06820d66f9da8ba4` |
| s390x | FerretDB | [wekan/FerretDB](https://github.com/wekan/FerretDB/releases/download/v1.48.0/ferretdb-s390x) | v1.48.0 | `6c7d61fbb8c79b2e8733be8f71910f710e8c5cd25208c451bdc513c8313b0340` |
| win64 | Node.js | [nodejs.org](https://nodejs.org/dist/v24.19.0/node-v24.19.0-win-x64.zip) | v24.19.0 | `57f71ab3652e797d84acddc79c81cc9ff1c6ddb2a1974cdb83f00fee9bff4c73` |
| win64 | FerretDB | [wekan/FerretDB](https://github.com/wekan/FerretDB/releases/download/v1.48.0/ferretdb-win64.exe) | v1.48.0 | `ea57e1bcd153b51d2065ab01515b21ec05d8f615444c15603ab8158b8a661dd2` |
This release adds the following new features:
**Windows on ARM** - a bundle whose every binary was already published.
<details>
<summary><a href="https://github.com/wekan/wekan/commit/8bb7b9ba6">Build a win-arm64 bundle</a>. Thanks to xet7.</summary>
WeKan could always have shipped this and simply did not. All three suppliers
publish the architecture: nodejs.org builds `node-v24.19.0-win-arm64.zip`
itself, [wekan/FerretDB](https://github.com/wekan/FerretDB) publishes
`ferretdb-win-arm64.exe`, and
[wekan/mongo-tools-patches](https://github.com/wekan/mongo-tools-patches)
publishes every tool as `-win-arm64.exe`.
`releases/resolve-node-source.sh` gains the platform and resolves it to
nodejs.org with a published SHA256, so it needs no node-patches build at all.
The job is the win64 one with the architecture changed: it builds on the x64
Windows runner exactly as win32 does, because the Meteor bundle is JavaScript,
the native modules are installed with `--ignore-scripts` and are not compiled
for the runner's architecture either way, and the only architecture-specific
things in the zip are the three binaries above, which are downloaded rather
than built.
**What cannot be added, checked at the same time: armv5 and armel.** FerretDB
and the MongoDB tools publish `armel` - they are Go, and Go still targets it -
but **Node.js does not exist for either**, and it cannot be built either: V8's
accepted `--arm-arch` list stops at armv6. No Node.js means no bundle, so no
Docker image and no snap either. armv6 was checked in the same pass and looked
like the same answer - nodejs.org publishes no 32-bit ARM at all for v24.19.0
and unofficial-builds has no `armv6l` - but there the SUPPORT was still in the
source and only the build was missing, which is what the next entry does.
</details>
**Raspberry Pi 1 and Zero** - the platform whose Node.js had to be built first.
<details>
<summary><a href="https://github.com/wekan/wekan/commit/d9e4cd57c">Build an armv6 bundle</a>. Thanks to xet7.</summary>
Every piece of the chain exists now, and the piece that was missing was
Node.js. nodejs.org dropped its ARMv6 binaries after Node 11 and
unofficial-builds has none, so
[wekan/node-patches](https://github.com/wekan/node-patches) gained an armv6
target - V8 still accepts `--arm-arch=armv6` and `configure.py` still carries
`is_arch_armv6()` with `vfp` among its valid ARM FPUs, so only the build was
missing - and [wekan/FerretDB](https://github.com/wekan/FerretDB) and
[wekan/mongo-tools-patches](https://github.com/wekan/mongo-tools-patches)
gained `GOARM=6` targets beside their armhf ones.
Their `armel` is `GOARM=5` and WOULD run on these boards, which is exactly why
it looks like a substitute and is not one: `GOARM=5` does floating point in
software, and an ARMv6 board has VFPv2.
The bundle builds in a `linux/arm/v6` container and takes `node-armv6`, and
`releases/resolve-node-source.sh` resolves it - naming `linux-armv6l` as the
upstream spelling even though nothing upstream will ever answer to it, so the
search it prints is honest about where it looked.
**No snap, and that is not an oversight.** The Snap Store has no armv6
architecture at all - its only 32-bit ARM is `armhf`, which is ARMv7-A
hard-float and will not run on an ARMv6 board. So armv6 ships as a bundle zip
and a `linux/arm/v6` Docker image, and `models/lib/snapArchitectures.js`
records that reason in `NOT_SNAP_ARCHITECTURES` beside i386's and armv7's.
Four tests found the four places a new platform has to be registered, which is
what they are for: `releases/expected-assets.sh` (or "Release all missing"
never notices the asset is absent), the resolver's mapping table, the
non-native bundle list, and the snap-platform exemption. Each list was updated
rather than the guard loosened.
**What is not verified: none of these binaries has been built yet.** The
Node.js one is a multi-hour ARM cross compile and the first CI run is its test.
Everything checkable from source was checked - V8's accepted `--arm-arch`
values, `configure.py`'s ARM handling, Go's `GOARM` semantics, and that zlib's
ARM SIMD is gated on `arm_fpu == "neon"`, so an armv6 build selects the scalar
code by itself and needs none of the NEON patching armv7 does.
</details>
<details>
<summary><a href="https://github.com/wekan/wekan/commit/f342d54d1">The Docker image gains it as a candidate platform, gated on a base that publishes linux/arm/v6</a>. Thanks to xet7.</summary>
**`TARGETARCH` does not identify a 32-bit ARM platform.** `linux/arm/v6` and
`linux/arm/v7` both arrive in the `Dockerfile` as `TARGETARCH=arm`; the CPU
generation is in `TARGETVARIANT`. The architecture `case` mapped `arm` straight
to `armhf`, so the moment armv6 existed as a bundle, an ARMv6 build would have
been handed the armhf zip — ARMv7-A instructions for a CPU that cannot execute
them. It now branches on the variant: `v6` takes the `armv6` bundle, `v7` and an
unset variant take `armhf`, and anything else exits. `v5` is armel: FerretDB and
the MongoDB tools publish it, but Node.js does not exist for ARMv5, so there is
no bundle and refusing is the only honest answer.
`linux/arm/v6` is in the docker job's optional platform list beside the others,
and the release then asks a question it never asked before: **does the base
image publish this platform?** For every other architecture that question is
uninteresting, because a base that lacks one fails the build. For 32-bit ARM it
does not fail — containerd treats a **lower** ARM variant as compatible, so a
`linux/arm/v6` request against a base with `arm/v5` and `arm/v7` quietly
resolves to `arm/v5`, Debian **armel**, soft float. The image would build on a
userland whose loader cannot start the hard-float `node-armv6` inside the
bundle. A silent downgrade is worse than a dropped platform.
So the job reads the base name out of the `Dockerfile` — no second copy of it —
asks `docker buildx imagetools inspect` what that base publishes, and drops a
candidate it lacks with a warning saying why. Today `debian:trixie` is `386`,
`amd64`, `arm64/v8`, `arm/v5`, `arm/v7`, `ppc64le`, `riscv64`, `s390x`: **no
`arm/v6`**, because Debian has no ARMv6 port — its 32-bit ARM ports are armel
and armhf, and ARMv6 hard-float is Raspberry Pi OS territory. **The armv6
bundle zip is unaffected**, and that is how an ARMv6 board runs WeKan today; the
image platform is wired end to end and turns itself on the day a base publishes
the variant, with nothing else to change.
Checked against the real registry rather than assumed: `debian:trixie`'s
manifest list was read, and the decide step was run against both that list
(armv6 drops, the other seven build) and a base that does publish `arm/v6`
(armv6 is included, paired with the `armv6` bundle).
`tests/releaseDockerPlatforms.test.cjs` pins the variant split, the refusal of
`v5`, the platform-to-bundle pairing, and that both loops ask the base — the
last one so that "just delete the check" cannot quietly become an image whose
Node.js will not start.
</details>
and reorganises the Admin Panel:
<details>
<summary><a href="https://github.com/wekan/wekan/commit/dcc6c8fe5">Version is five tables with a heading each, and says what WeKan is installed as</a>. Thanks to xet7.</summary>
Admin Panel / Settings / Version was ONE table of 38 rows, in which the WeKan
version, the OS load average, the DDP transport and a V8 heap counter were the
same kind of thing: a flat list read top to bottom, with no way to jump to the
part you came for.
It is five tables now, each under a small heading, in the order somebody
debugging reads them — **Platform** (what this is), **OS** (what it runs on),
**Meteor** (how it talks to the client), **Database** and **Node**. Reactivity,
reactivity order and the DDP transport moved to Meteor, where they belong: they
are how the client is fed, and they were the rows most often read as database
settings. Whether an OpLog *exists* stays with the database, because that is a
property of it. Nothing was dropped — a test lists all 38 rows by name and
requires each to still be shown.
**The new row is what WeKan is installed as: `bundle.zip`, `Snap`, `Docker` or
`Sandstorm`.** It is the first thing a support answer turns on and the pane
never said it: the same version keeps its data somewhere else, carries a
different database and gives the admin different reach in each of the four.
The row's label is translated (`package`, "Package"); **the four values never
are**, and none of them is a translation key — they are the names of the things
themselves, not words describing them, so what an admin reads is the same string
they can put in an issue, search the docs for and grep a log with, in every
language.
`models/lib/platformPackaging.js` decides it most-specific-first — an explicit
`WEKAN_PACKAGING` wins, then Sandstorm, then snapd's own `SNAP`/`SNAP_NAME`,
then a container runtime's marker file, then the bundle. Sandstorm and Snap are
asked BEFORE the container markers on purpose: a grain **is** a container and a
confined snap can look like one, so the other order answers "Docker" for both.
It claims nothing it cannot know: there is no "source checkout" answer, because
a `meteor run` and an unpacked bundle are identical from inside the process.
The detection is a pure function — it takes the environment, the Sandstorm flag
and a file-exists callback — so all nine of its tests run in a sandbox with no
snap, no container and no grain: that an empty `SNAP` is not a snap, that an
empty `WEKAN_PACKAGING` falls through instead of blanking the field, and that an
unreadable filesystem root answers `bundle.zip` rather than throwing away an
admin's Version page.
The headings are deliberately smaller than the pane title above them, and a test
compares the two font sizes instead of trusting the CSS to stay that way: five
headings at the pane title's size read as five pane titles, and "Version" is
lost among them.
</details>
and fixes the following bugs:
**The snap builds** - what they download, and what the store does with the
result.
<details>
<summary><a href="https://github.com/wekan/wekan/commit/4e9be22f9">Caddy has no armhf archive, and a store hiccup is not a bad snap</a>. Thanks to xet7.</summary>
Two failures in the v10.78 snap jobs, neither of them a problem with WeKan.
**armhf asked for a Caddy architecture that does not exist.** With the
`libcurl4t64` fix in, the armhf build got past the stage-packages and died
further along:
```
:: Downloading Caddy 2.11.4 (linux/armhf) from GitHub releases...
:: curl: (22) The requested URL returned error: 404
'override-build' in part 'caddy' failed with code 1.
```
Caddy is built by Go and its release assets carry **Go's** architecture names,
not Debian's. There is no `linux_armhf` archive and there never has been - the
32-bit ARM ones are `armv5`, `armv6` and `armv7` - and the case statement had no
armhf branch, so it fell through to a default that passed the Debian name
straight into the URL. The "fall back to the pinned version" path then retried
the same wrong name, so the failure read as *"Caddy stopped publishing this
architecture"* when it was this file's mapping all along.
armhf maps to `armv7`, not `armv6`: Debian armhf's baseline is ARMv7-A with
VFPv3-D16 hard-float, and Go's armv7 build is `GOARM=7`, which is exactly that.
This is **not** the armhf/armv7 distinction that matters for Node.js in
[wekan/node-patches](https://github.com/wekan/node-patches) - that one is about
NEON, and `GOARM=7` does not use NEON. Checked against the actual release: all
six mapped URLs answer and `linux_armhf` 404s. The default branch now names the
problem and stops, instead of guessing a name and letting a 404 blame the wrong
project.
**Three good snaps were lost to a store hiccup.** riscv64, ppc64el and s390x
each built on Launchpad, downloaded, and were then refused:
```
Status: error while processing
Issues while processing snap:
- binary_sha3_384: Error checking upload uniqueness.
```
That is the store failing its **own** duplicate check on a digest it had just
computed - a server-side error, not a bad snap - while the message the job
printed was about *"is not a valid file"*, credentials and ACLs, none of which
applied. The upload is retried three times with a backoff now, and the give-up
message says the snap is fine and nothing here needs changing. The retry stays
narrow on purpose: a rejected file, unparseable credentials or a missing ACL
will be rejected identically three times, and retrying those only buries the one
message that says what to fix - so the classifier is tested against all four,
not just the one that happened.
</details>
**The snap on the next base** - what `snapcraft-core26.yaml` builds.
<details>
<summary><a href="https://github.com/wekan/wekan/commit/664b8fde6">The next base declares all six architectures too, armhf included</a>. Thanks to xet7.</summary>
`snapcraft.yaml` declares six platforms — amd64, arm64, armhf, ppc64el, riscv64,
s390x — and every one is built: two natively, four on Launchpad.
`snapcraft-core26.yaml` declared **five**. armhf was missing, and nothing could
notice: that file is not built by any release, it is the next base kept so the
move can be tested before it is made. The day core26 becomes the base, armhf
would simply stop being published, and the only symptom would be a store column
going stale — exactly as `wekan-ondra`'s armhf did at 0.22.
Adding the platform alone would have been nominal. The same file still carried
the **pre-t64** stage-package names — `libssl3`, `libcurl4`,
`libgoogle-perftools4` — and those are precisely what failed armhf on core24
twice: Ubuntu's 64-bit `time_t` transition renamed them, the 64-bit
architectures kept a compatibility `Provides` so the old spelling resolves
there, and armhf did not. armhf on core26 would have failed on the first thing
it tried, in the way this repository has already debugged. It has the t64 names
now, and its Caddy branch — which already mapped armhf to Go's `armv7` — no
longer claims to be unreachable.
Two guards, both checked in the failing direction as well: the two snapcraft
files must declare the SAME set of architectures, and the stage-package check
runs over BOTH files instead of only the one the release builds.
Nothing here changes what the release builds today. core24 stays the built base,
and `wekan`'s armhf snap is still waiting on the Caddy armhf fix above.
</details>
**The release notes** - what the provenance table can say about amd64.
<details>
<summary><a href="https://github.com/wekan/wekan/commit/e59680519">The amd64 provenance scripts were never found, only never complained</a>. Thanks to xet7.</summary>
The amd64 build failed with exit 127, after the bundle had been zipped and
checksummed:
```
a95d331b… wekan-10.78-amd64.zip
bash: releases/record-provenance.sh: No such file or directory
bash: releases/ferretdb-latest-tag.sh: No such file or directory
```
The step runs `cd .build` first, so nothing relative in it means what it looks
like it means - and that is **two** bugs, of which only the second had ever been
visible. `bash releases/record-provenance.sh` resolves against `.build/`, which
has no `releases/`, so it had printed *"No such file or directory"* on every run
since it was written and the `|| true` on the end swallowed it. amd64 had
therefore never recorded any provenance at all, and the only symptom was its
absence from the table - so the missing-directory fix above repaired the half
that showed and left the half that did not.
What made it loud is that the FerretDB tag lookup added alongside it is an
**assignment**. Under `set -e`, and every GitHub `run:` is `bash -e`,
`VAR="$(cmd)"` ends the step when the command fails - so a line that had been
quietly doing nothing for months became a hard failure of the whole amd64 build.
Every path in that step is absolute now, and every `FERRET_TAG` assignment
across all seven sites ends `|| true`: the bundle is the deliverable, and which
version string reaches a markdown cell is not worth failing a good build for.
Only amd64's step `cd`s - the other six run from the workspace root, which is
exactly what the v10.77 run showed, since all six uploaded provenance and amd64
did not.
The guard added with it is the general form rather than this one line: it walks
back from every provenance call to its step header and requires an absolute path
whenever a `cd` runs inside that step.
</details>
and documents which CPU platforms each package is built for:
**The Docker image and the snap** - a page each for what they are built for.
<details>
<summary><a href="https://github.com/wekan/wekan/commit/5ec9f3ae5">A page for the Docker image's CPU platforms, beside the one the snap already had</a>. Thanks to xet7.</summary>
"Which CPUs is this published for, and why not that one" was answerable for the
snap and nowhere else, so the same page now exists for the image:
`docs/Platforms/FOSS/Container/Docker/CPU-platforms.md`. It carries the
platform matrix with each platform's `TARGETARCH`, `TARGETVARIANT` and bundle,
how the set is decided on every release from what the base image publishes and
which bundles landed, the three names that differ between Docker, Debian and the
WeKan bundles, and one section per platform that is deliberately NOT an image:
loong64 (no base image exists at any tag), armv6 (gated on a base with
`arm/v6`), armv7 (the one 32-bit ARM slot must carry the armhf baseline) and the
Windows and macOS bundles. It ends with why the FerretDB image covers more
platforms than the WeKan one — `FROM scratch` around a static Go binary needs no
userland at all.
The snap's page gains the matching armv6 section — the Snap Store has no armv6
architecture, and its only 32-bit ARM is armhf, which an ARMv6 board cannot
run — and a table of all fifteen bundles against which six become snaps, so
"it is missing" and "it cannot be there" stop looking alike. The two pages link
each other, because the answer differs between them.
`docs/Databases/FerretDB/1/README.md` said the per-architecture FerretDB binary
was embedded in the bundles "for ppc64le, s390x, riscv64". Every bundle carries
one; those three are part of a longer list of platforms where it is the DEFAULT
because MongoDB publishes no server. It now lists all seventeen built binaries
and separates the three 32-bit ARM builds that are not variants of each other:
`armhf` is `GOARM=7`, `armv6` is `GOARM=6`, `armel` is `GOARM=5` software
floating point.
</details>
**The snap store** - what it actually holds, and what it cannot.
<details>
<summary><a href="https://github.com/wekan/wekan/commit/cf0c347b2">The snap page says what the store holds at 10.78, and why the empty squares differ</a>. Thanks to xet7.</summary>
The table of what each snap has was "as of 10.76" and marked every empty square
the same way: *built by snapcraft.yaml but that snap has no revision for it yet;
uploading one is all that is needed*. For eight of the twelve squares that is
not true, and it sends whoever reads it at the wrong job.
Three marks now, because there are three situations. `wekan`'s **armhf** is
BUILT by the release and missing from the store: snapcraft.yaml declares it,
`snap-launchpad` builds it, and it has been failing - most recently on Caddy,
which publishes no `linux_armhf` archive because its asset names are Go's.
The exotic squares of `wekan-ondra` and `wekan-gantt-gpl` are **not pending
uploads at all**: the `snap-variants` job has four matrix entries, each variant
on amd64 and arm64, and the ppc64el/s390x/riscv64/armhf builds come from
`snap-launchpad`, which builds only the `wekan` name. And `wekan-ondra`'s
armhf **0.22 is a fossil**: there is no newer revision to promote, and nothing
currently builds one.
riscv64 moved from missing to published since 10.76, so `wekan` is five of six.
Every published architecture is on all four channels, which is the
release-to-every-channel work holding.
</details>
and documents how to work on these repositories:
**CLAUDE.md and AGENTS.md** - who maintains them, what is in `.tools/`, and how
each repository's changelog is written.
<details>
<summary><a href="https://github.com/wekan/wekan/commit/35dd10b89">They say who maintains these repositories and who commits, before any identity check</a>. Thanks to xet7.</summary>
Both files opened with an identity CHECK - *"maintainer mode only when the
identity is exactly Lauri Ojansivu"* - which says what to do with an identity
but never says whose repositories these are. They are xet7's: WeKan, the
FerretDB v1 fork, node-patches and mongo-tools-patches. That is now the first
thing both files say, and the commit author follows from it rather than from a
conditional.
Two rules are spelled out under it. **No commit, pull-request body or CHANGELOG
line ever attributes work to an AI** - no `Co-Authored-By`, no "Generated with",
no assistant or model name - and CODE_OF_CONDUCT.md is cited as where that comes
from: *"mention only those participants that are human"*. And **a missing or
wrong git identity in one of these checkouts is to be SET, not worked around**:
the `.tools/` clones can come up with no `user.name`/`user.email` at all -
mongo-tools-patches did - which would author a commit as whatever the machine's
default is.
</details>
<details>
<summary><a href="https://github.com/wekan/wekan/commit/d07794811">What is in .tools/, and the changelog format of every repository under it</a>. Thanks to xet7.</summary>
`.tools/` was one sentence naming three clones. It is now the two kinds of thing
that directory holds, because they are treated differently: **companion git
repositories** - wekan/FerretDB on `main-v1`, node-patches and
mongo-tools-patches on `main`, Secretchronicles/TSC on `devel`,
sandstorm-io/sandstorm - each with their own history, branches, changelog and
release flow, cloned on demand by `build.sh`'s `ensure_tool_repo`; and
**unpacked toolchains** that are downloads rather than repositories -
`node-v<version>-linux-<arch>`, `go` with its caches, `.meteor`, the TSC
AppImage - to be deleted and re-fetched freely.
**No CLAUDE.md or AGENTS.md under `.tools/`.** node-patches and
mongo-tools-patches each had a pair, and they were removed: the rules are
identical for all of these repositories and a second copy drifts from the first.
A fact true of one repository only belongs in that repository's own README or
docs - and an instruction file found there is to be removed rather than updated.
**Each repository's changelog is written in the format its own file already
uses**, as a table: WeKan, node-patches and mongo-tools-patches use the WeKan
format; wekan/FerretDB keeps upstream FerretDB's; and TSC uses **GNU ChangeLog**
- a `YYYY-MM-DD Name <email>` header over tab-indented `* Fix:` entries in a
file called `CHANGELOG` with no extension. The reason is the reader: a FerretDB
release is read beside upstream's, and a TSC entry beside a decade of GNU
entries.
</details>
<details>
<summary><a href="https://github.com/wekan/wekan/commit/bf1f7aea4">TSC is xet7's too, under another organisation</a>. Thanks to xet7.</summary>
The commit above read Secretchronicles/TSC's remote, saw it was not a `wekan/`
repository, and concluded it was somebody else's project xet7 contributes to. It
is his: the organisation is Secretchronicles rather than wekan, and that is the
only difference. His GitHub profile says it in three words - *"WeKan and TSC
maintainer"* - and the files cite it, so the next reader checks a source instead
of inferring from a remote URL as that one did.
So maintainer mode covers it - commit directly to `devel`, no pull request, same
author, no AI attribution - and the files name the one `.tools/` repository that
really is somebody else's: `sandstorm-io/sandstorm`, cloned for reference. What
does NOT follow from maintaining it is WeKan's house style: TSC keeps its own
GNU ChangeLog and its own release process.
</details>
Thanks to above GitHub users for their contributions and translators for their
translations.
# v10.78 2026-08-09 WeKan ® release
**In short:** the **AppImage** workflow. It built both AppImages, started them,
@@ -464,7 +1206,9 @@ at random is worse than showing both.
`cd .build` before `mkdir -p provenance`, so the rows went to
`.build/provenance` while the upload looked at `provenance/` from the workspace
root and found nothing. Every other build job records from the workspace root,
which is why only this one was affected.
which is why only this one was affected. That turned out to be half the story:
the scripts themselves were not being found either, which the next release
fixes.
**Six platforms said Version `latest`.** amd64, arm64, win64, win32, mac-arm64
and mac-x64 passed the literal string; only the extra-architecture job asked
+109 -23
View File
@@ -2,7 +2,35 @@
Claude Code reads this file at the repo root before doing work here. Follow it.
## First: are you the maintainer or a contributor?
## First: who maintains this, and who is committing?
**WeKan, the `wekan/` repositories cloned under `.tools/`, and
[Secretchronicles/TSC](https://github.com/Secretchronicles/TSC) are all maintained by
Lauri Ojansivu (xet7) `<x@xet7.org>`** — [wekan/wekan](https://github.com/wekan/wekan),
[wekan/FerretDB](https://github.com/wekan/FerretDB),
[wekan/node-patches](https://github.com/wekan/node-patches),
[wekan/mongo-tools-patches](https://github.com/wekan/mongo-tools-patches) and TSC,
which is under the **Secretchronicles** organisation rather than **wekan** and is his
all the same — his GitHub profile, [xet7](https://github.com/xet7), says exactly that:
*"WeKan and TSC maintainer"*. Work done on the maintainer's behalf is committed as
**`Lauri Ojansivu <x@xet7.org>`** — that author, in every one of those repositories,
every time. Two rules follow from it and neither has an exception:
- **Never attribute a commit to an AI.** No `Co-Authored-By:` trailer, no "Generated
with", no assistant or model name — not in the commit message, not in a pull-request
body, not in the CHANGELOG. [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) is where this
comes from: *"For pull requests, mention only those participants that are
**human**."* A `Thanks to ... and xet7 !` line credits people — the issue reporter
and xet7 — never a tool.
- **If the git identity is missing or wrong in one of these checkouts, set it; do not
commit under something else.** The `.tools/` clones are made by `build.sh` inside
this checkout and can come up with no `user.name`/`user.email` of their own, which
would silently author a commit as whatever the machine's default is:
```
git -C .tools/<repo> config user.name 'Lauri Ojansivu'
git -C .tools/<repo> config user.email 'x@xet7.org'
```
Check the current git identity before committing or releasing:
@@ -10,16 +38,25 @@ Check the current git identity before committing or releasing:
git config user.name && git config user.email
```
- **Maintainer mode** — ONLY when the identity is exactly
`Lauri Ojansivu <x@xet7.org>` (name `Lauri Ojansivu`, email `x@xet7.org`). Then, and
only then: commit **directly to the current branch** as `Lauri Ojansivu <x@xet7.org>`
with no AI trailer and no pull request, and the **publishing / release steps** below
are available.
- **Contributor mode** — any other git identity. Then: do **not** commit directly to
the branch and do **not** run any release/publishing step. Make changes on a branch
and open a **pull request** for the maintainer to review. The "commit as Lauri
Ojansivu", "commit directly", and all release instructions below are **maintainer-only
and do not apply to you**.
- **Maintainer mode** — the identity is `Lauri Ojansivu <x@xet7.org>` (name
`Lauri Ojansivu`, email `x@xet7.org`), or it is unset in a checkout of one of the
repositories above, which means it is to be SET to that as above rather than worked
around. Then: commit **directly to the current branch** as
`Lauri Ojansivu <x@xet7.org>` with no AI trailer and no pull request, and the
**publishing / release steps** below are available.
- **Contributor mode** — the identity is somebody ELSE, in a fork or a clone of your
own. Then: do **not** commit directly to the branch and do **not** run any
release/publishing step. Make changes on a branch and open a **pull request** for
the maintainer to review, and keep that pull request free of AI attribution too.
The "commit as Lauri Ojansivu", "commit directly", and all release instructions
below are **maintainer-only and do not apply to you**.
Maintainer mode covers TSC as well: commit directly to its `devel` branch, no pull
request, same author and no AI attribution. What it does NOT bring along is WeKan's
house style — TSC keeps its own **GNU ChangeLog** `CHANGELOG` and its own release
process, because a project is read on its own terms (see the CHANGELOG section below).
The one repository under `.tools/` that is somebody else's is `sandstorm-io/sandstorm`,
cloned for reference only.
Everything below marked as maintainer-specific (committing directly, the exact commit
author, and the entire "Making a release" / publishing flow) applies only in maintainer
@@ -121,26 +158,75 @@ pushed to Transifex as if it were human.
"Co-Authored-By" or any other AI trailer, directly to the `main` branch of WeKan and
the `main-v1` branch of the FerretDB fork. **Do not make pull requests.** (Contributors
do the opposite: work on a branch and open a pull request — see the top section.)
- Lauri Ojansivu (xet7) maintains WeKan (https://wekan.fi) and the FerretDB v1 fork.
This is the same rule as the top section, restated where the release work is: one
author, `Lauri Ojansivu <x@xet7.org>`, and no AI attribution anywhere.
- Lauri Ojansivu (xet7) maintains WeKan (https://wekan.fi), the FerretDB v1 fork, and
the two patch repositories under `.tools/` — node-patches and mongo-tools-patches.
- Directory structure:
- `wekan` — this repo (https://github.com/wekan/wekan); see
`docs/DeveloperDocs/Directory-Structure.md`; `CHANGELOG.md` at root.
- `../w/wekan.fi` — the WeKan website.
- `.tools/` — companion repos cloned INSIDE this checkout, in one directory
that `.gitignore` and `.meteorignore` already exclude (they used to be one
ignored subdirectory each at the repo root). `build.sh`'s `ensure_tool_repo`
clones one on demand, so a fresh checkout needs no manual setup:
`.tools/FerretDB`, `.tools/node-patches`, `.tools/mongo-tools-patches`.
- `.tools/FerretDB` (cloned on demand) — https://github.com/wekan/FerretDB, its own
`CHANGELOG.md`. FerretDB `.go` files must contain **no** application-specific names
(say "the client" / "a Meteor 3 driver" / a bare `#NNNN`); its `CHANGELOG.md` may
use `wekan/wekan#NNNN`.
- `.tools/sandstorm` (when present) — https://github.com/sandstorm-io/sandstorm.
- `.tools/` — everything that is NOT part of this repository but is needed to
build, test and release it, in ONE directory that `.gitignore` and
`.meteorignore` already exclude (each used to need its own ignore entry at
the repo root), so nothing in it can reach a commit or a Meteor rebuild. Two
different kinds of thing live there, and the difference matters:
**Companion git repositories.** Separate repositories with their own history,
branches, changelog and release flow — a commit here is never a commit there.
`build.sh`'s `ensure_tool_repo` clones one on demand (SSH first, HTTPS
second), so a fresh checkout needs no manual setup:
| Path | Repository | Branch | What it is |
| --- | --- | --- | --- |
| `.tools/FerretDB` | wekan/FerretDB | `main-v1` | the FerretDB v1 fork WeKan ships as its default database |
| `.tools/node-patches` | wekan/node-patches | `main` | patches to upstream Node.js; builds the `node-<platform>` binaries the bundles, the Docker image and the snap embed |
| `.tools/mongo-tools-patches` | wekan/mongo-tools-patches | `main` | patches to the MongoDB Database Tools; builds `<tool>-<arch>` |
| `.tools/TSC` | Secretchronicles/TSC | `devel` | the game xet7 also maintains — same author and maintainer mode, its own GNU ChangeLog and release process |
| `.tools/sandstorm` | sandstorm-io/sandstorm | — | upstream Sandstorm, when present — somebody else's project, cloned for reference |
**Unpacked toolchains and caches.** Downloads, not repositories — put there by
the sandbox instructions in `docs/Security/Sandboxes/vscode/README.md`, deleted
and re-fetched freely, never committed anywhere:
`node-v<version>-linux-<arch>/` (the Node.js the test suites are run with),
`go/` with `gopath/`, `gomodcache/` and `gocache/` (FerretDB's Go builds),
`.meteor/` when `HOME` is pointed at `.tools`, and the `TSC*` AppImage.
- **Do NOT add a `CLAUDE.md` or an `AGENTS.md` to any repository under
`.tools/`.** node-patches and mongo-tools-patches each had a pair and they were
REMOVED on purpose: the rules are the same for every one of these repositories,
and a second copy of a rule drifts from the first. THIS file, and its `AGENTS.md`
twin beside it, are where they live for all of them. Something true of only one
of those repositories goes in that repository's own `README.md` or `docs/`,
never in a new instruction file — and if you find one there, remove it rather
than updating it.
- `.tools/FerretDB` specifics — FerretDB `.go` files must contain **no**
application-specific names (say "the client" / "a Meteor 3 driver" / a bare
`#NNNN`); its `CHANGELOG.md` may use `wekan/wekan#NNNN`.
### CHANGELOG
- **Every repository writes its changelog in the format that repository's own file
already uses.** Open its changelog, read the entries above the place you are
adding one, and match them — never import another project's shape into it. The
five that come up here:
| Repository | File | Format |
| --- | --- | --- |
| `wekan/wekan` | `CHANGELOG.md` | the WeKan format this section describes: `# Platforms`, `# TODO Later`, then `# v<MAJOR>.<MINOR> YYYY-MM-DD WeKan ® release` sections of `<details>` entries whose `<summary>` links the commit |
| `wekan/node-patches` | `CHANGELOG.md` | the same WeKan format, with `# Upcoming node-patches release` |
| `wekan/mongo-tools-patches` | `CHANGELOG.md` | the same WeKan format, with `# Upcoming mongo-tools-patches release` |
| `wekan/FerretDB` | `CHANGELOG.md` | **upstream FerretDB's** format, not WeKan's: `## [v1.48.0](tag URL) (YYYY-MM-DD)` and `### New Features 🎉` / `### Fixed 🐛` / `### Other Changes 🤖` bullets ending `by @xet7. Thanks to xet7.` |
| `Secretchronicles/TSC` | `CHANGELOG` (no extension) | **GNU ChangeLog** format: a `YYYY-MM-DD Name <email>` header line, then TAB-indented `* Version …` / `* Fix: …` / `* Misc: …` entries, wrapped and continued with further tabs, each ending `(by Name)` |
The reason is the reader, not consistency for its own sake: a FerretDB release is
read beside upstream FerretDB's releases, and a TSC entry beside a decade of GNU
ChangeLog entries. A WeKan-shaped `<details>` block in either would be the odd one
out and would break the tooling that parses them. When this file and the file being
edited disagree, **the file being edited wins** — and everything below in this
section is about the WeKan format specifically.
- During development, add entries under a new `# Upcoming WeKan ® release` section above
the newest release (FerretDB uses `## Upcoming FerretDB release`). Do **not** hand-edit
the newest release (FerretDB uses `## Upcoming FerretDB release`; the patch repos use
`# Upcoming <repo> release`). Do **not** hand-edit
`package.json` or any other version reference — the release workflow bumps those.
- **The file's shape, top to bottom** — keep it exactly as it is now:
1. `# Platforms` — the line `Newest WeKan at these platforms:` and the Install /
+25 -2
View File
@@ -3,6 +3,14 @@
# arch this image targets - amd64, arm64, 386, arm/v7, ppc64le, riscv64, s390x -
# so ONE base covers them all, and it is the same base WeKan's per-arch .zip
# bundles are already built in (releases/... build-extra-arches).
#
# The ONE it does not ship is arm/v6: debian:trixie's manifest list has arm/v5
# and arm/v7 and nothing between them. That matters because containerd treats a
# LOWER ARM variant as compatible, so a linux/arm/v6 request does not fail - it
# quietly resolves to the arm/v5 (armel, SOFT-float) image, whose loader and
# glibc cannot run the hard-float node-armv6 in the armv6 bundle. The docker job
# therefore asks this base what it publishes and drops a platform it lacks; see
# docs/Platforms/FOSS/Container/Docker/CPU-platforms.md.
FROM debian:trixie
LABEL maintainer="wekan"
LABEL org.opencontainers.image.ref.name="debian"
@@ -12,7 +20,7 @@ LABEL org.opencontainers.image.source="https://github.com/wekan/wekan"
# TARGETARCH and TARGETVARIANT are automatically provided by Docker Buildx
ARG TARGETARCH
ARG TARGETVARIANT
ARG VERSION=10.78
ARG VERSION=10.80
ARG DEBIAN_FRONTEND=noninteractive
ENV BUILD_DEPS="apt-utils gnupg wget bzip2 g++ curl libarchive-tools build-essential git ca-certificates python3 unzip"
@@ -210,7 +218,22 @@ case "${TARGETARCH}" in
"s390x") WEKAN_ARCH="s390x" ;;
"riscv64") WEKAN_ARCH="riscv64" ;;
"386") WEKAN_ARCH="i386" ;;
"arm") WEKAN_ARCH="armhf" ;;
# BOTH linux/arm/v6 and linux/arm/v7 arrive here as TARGETARCH=arm - the CPU
# generation is in TARGETVARIANT, not in TARGETARCH - so this branch MUST read
# the variant. Mapping "arm" straight to armhf, as it did, would hand an ARMv6
# board (Raspberry Pi 1, Zero) the armhf bundle, which is built to Debian's
# ARMv7-A baseline and whose instructions that board cannot execute.
"arm")
case "${TARGETVARIANT}" in
"v6") WEKAN_ARCH="armv6" ;;
# v7, and an unset variant, are Debian's armhf port: ARMv7-A,
# VFPv3-D16 hard-float. That is what linux/arm/v7 runs.
"v7"|"") WEKAN_ARCH="armhf" ;;
# v5 is armel: FerretDB and the MongoDB tools publish it (they are Go),
# but Node.js does not exist for ARMv5 at all, so there is no bundle to
# put in an image and refusing is the only honest answer.
*) echo "Unsupported 32-bit ARM variant: ${TARGETVARIANT} (only v6 and v7 have a WeKan bundle)"; exit 1 ;;
esac ;;
*) echo "Unsupported architecture: ${TARGETARCH}${TARGETVARIANT:+/${TARGETVARIANT}}"; exit 1 ;;
esac
+1 -1
View File
@@ -1,5 +1,5 @@
appId: wekan-public/apps/77b94f60-dec9-0136-304e-16ff53095928
appVersion: "v10.78.0"
appVersion: "v10.80.0"
files:
userUploads:
- README.md
+306
View File
@@ -1457,6 +1457,312 @@ THEME - Corteza
/* === END Corteza THEME === */
/* ===============
THEME - Apple Glass Pastel
=================*/
.board-color-appleglasspastel {
background:
radial-gradient(60% 50% at 85% 5%, rgba(255, 200, 220, 0.55), transparent 60%),
radial-gradient(55% 50% at 5% 25%, rgba(180, 215, 255, 0.55), transparent 65%),
radial-gradient(55% 50% at 95% 95%, rgba(200, 230, 255, 0.5), transparent 60%),
radial-gradient(70% 60% at 0% 100%, rgba(230, 215, 255, 0.5), transparent 65%),
linear-gradient(180deg, #f6f7fb 0%, #eef0f7 100%);
color: #111827;
}
.board-color-appleglasspastel#header,
.board-color-appleglasspastel#header-quick-access,
.board-color-appleglasspastel.sk-spinner div,
.board-color-appleglasspastel .setting-content .content-body .side-menu ul li.active,
.board-color-appleglasspastel .setting-content .content-body .side-menu ul li.active:hover {
background: #2563eb;
color: #fff;
}
.board-backgrounds-list .board-color-appleglasspastel.background-box,
.public-board-row.board-color-appleglasspastel,
.board-list .board-color-appleglasspastel a {
background:
radial-gradient(80% 70% at 80% 0%, rgba(255, 200, 220, 0.7), transparent 62%),
radial-gradient(70% 80% at 0% 15%, rgba(180, 215, 255, 0.75), transparent 66%),
radial-gradient(75% 70% at 100% 100%, rgba(230, 215, 255, 0.7), transparent 62%),
linear-gradient(180deg, #f6f7fb 0%, #eef0f7 100%);
color: #111827 !important;
}
.board-color-appleglasspastel#header-quick-access {
border-bottom: 1px solid rgba(255, 255, 255, 0.55);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
}
.board-color-appleglasspastel#header #header-main-bar,
.board-color-appleglasspastel#header-quick-access,
.board-color-appleglasspastel .boards-left-menu .menu-item.active a,
.board-color-appleglasspastel .boards-left-menu .menu-item.active a:hover {
background: #2563eb;
}
.board-color-appleglasspastel#header ul li.current,
.board-color-appleglasspastel#header-quick-access ul li.current {
border-bottom: 4px solid #dbeafe;
}
.board-color-appleglasspastel#header-quick-access #header-new-board-icon,
.board-color-appleglasspastel#header-quick-access #header-user-bar,
.board-color-appleglasspastel#header-quick-access ul li,
.board-color-appleglasspastel#header-quick-access a,
.board-color-appleglasspastel#header .board-header-btn,
.board-color-appleglasspastel#header .board-header-btn i {
color: #fff;
}
.board-color-appleglasspastel#header ul li:hover,
.board-color-appleglasspastel#header-quick-access ul li:hover,
.board-color-appleglasspastel .board-header-btn:hover {
background: rgba(255, 255, 255, 0.16);
border-radius: 10px;
}
.board-color-appleglasspastel#header #header-main-bar .board-header-btn.emphasis {
background: #1e3a8a;
box-shadow: 0 4px 16px rgba(37, 99, 235, 0.12), 0 1px 2px rgba(0,0,0,0.04);
}
.board-color-appleglasspastel#header #header-main-bar .board-header-btn.emphasis:hover,
.board-color-appleglasspastel#header #header-main-bar .board-header-btn.emphasis .board-header-btn-close {
background: #1d4ed8;
}
.board-color-appleglasspastel#header #header-main-bar .board-header-btn.emphasis:hover .board-header-btn-close {
background: #1e3a8a;
}
.board-color-appleglasspastel.board-wrapper {
background:
radial-gradient(60% 50% at 85% 5%, rgba(255, 200, 220, 0.55), transparent 60%),
radial-gradient(55% 50% at 5% 25%, rgba(180, 215, 255, 0.55), transparent 65%),
radial-gradient(55% 50% at 95% 95%, rgba(200, 230, 255, 0.5), transparent 60%),
radial-gradient(70% 60% at 0% 100%, rgba(230, 215, 255, 0.5), transparent 65%),
linear-gradient(180deg, #f6f7fb 0%, #eef0f7 100%);
}
.board-color-appleglasspastel .board-canvas {
scrollbar-color: rgba(37, 99, 235, 0.35) rgba(255, 255, 255, 0);
scrollbar-width: thin;
}
.board-color-appleglasspastel .swimlane {
background: transparent;
}
.board-color-appleglasspastel .swimlane .swimlane-header-wrap {
background: rgba(255, 255, 255, 0.45);
backdrop-filter: blur(24px) saturate(180%);
-webkit-backdrop-filter: blur(24px) saturate(180%);
border-bottom: 1px solid rgba(255, 255, 255, 0.55);
}
.board-color-appleglasspastel .swimlane-header {
color: #0f172a;
font-weight: 600;
}
.board-color-appleglasspastel .list {
background: rgba(255, 255, 255, 0.65);
backdrop-filter: blur(24px) saturate(180%);
-webkit-backdrop-filter: blur(24px) saturate(180%);
border: 1px solid rgba(255, 255, 255, 0.55);
border-inline-start: none;
border-radius: 18px;
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.06);
color: #111827;
margin: 10px 0;
padding-bottom: 8px;
}
.board-color-appleglasspastel .list-header {
background: rgba(255, 255, 255, 0.45);
border-bottom: 1px solid rgba(229, 231, 235, 0.75);
border-radius: 18px 18px 0 0;
}
.board-color-appleglasspastel .list-header .list-header-name,
.board-color-appleglasspastel .list-header .viewer,
.board-color-appleglasspastel .minicard-title {
color: #0f172a;
}
.board-color-appleglasspastel .list-body {
margin-top: 8px;
padding: 11px;
scrollbar-color: rgba(37, 99, 235, 0.35) rgba(255, 255, 255, 0);
scrollbar-width: thin;
}
.board-color-appleglasspastel .minicard,
.board-color-appleglasspastel .card-details,
.board-color-appleglasspastel.pop-over,
.board-color-appleglasspastel .sidebar {
background: rgba(255, 255, 255, 0.72);
backdrop-filter: blur(24px) saturate(180%);
-webkit-backdrop-filter: blur(24px) saturate(180%);
border: 1px solid rgba(255, 255, 255, 0.55);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
color: #111827;
}
.board-color-appleglasspastel .minicard {
border-radius: 12px;
padding: 10px 10px 4px 10px;
}
.board-color-appleglasspastel .minicard:hover:not(.minicard-composer),
.board-color-appleglasspastel .is-selected .minicard,
.board-color-appleglasspastel .draggable-hover-card .minicard {
background: rgba(239, 246, 255, 0.88);
}
.board-color-appleglasspastel .is-selected .minicard {
border-inline-start: 3px solid #2563eb;
}
.board-color-appleglasspastel .card-details {
border-radius: 18px;
}
.board-color-appleglasspastel .card-details-header {
background: rgba(239, 246, 255, 0.78);
border-bottom: 1px solid rgba(229, 231, 235, 0.75);
color: #0f172a;
}
.board-color-appleglasspastel .card-details-item-title,
.board-color-appleglasspastel .card-details-left .viewer p,
.board-color-appleglasspastel .activity-desc .activity-member {
color: #111827;
}
.board-color-appleglasspastel .quiet,
.board-color-appleglasspastel .quiet a,
.board-color-appleglasspastel .activity-desc,
.board-color-appleglasspastel .sidebar-list-item-description {
color: #6b7280;
}
.board-color-appleglasspastel .list.list-composer,
.board-color-appleglasspastel .list-body .open-minicard-composer,
.board-color-appleglasspastel .list.list-composer .open-list-composer {
background: rgba(255, 255, 255, 0.45);
border-radius: 12px;
color: #6b7280;
}
.board-color-appleglasspastel .list-body .open-minicard-composer:hover,
.board-color-appleglasspastel .list.list-composer .open-list-composer:hover,
.board-color-appleglasspastel.pop-over .pop-over-list li a:not(.disabled):hover,
.board-color-appleglasspastel .sidebar .sidebar-content .sidebar-btn:hover,
.board-color-appleglasspastel .sidebar-list li a:hover {
background: rgba(219, 234, 254, 0.78);
color: #1e3a8a;
}
.board-color-appleglasspastel button[type=submit].primary,
.board-color-appleglasspastel input[type=submit].primary,
.board-color-appleglasspastel button.primary,
.board-color-appleglasspastel input.primary,
.board-color-appleglasspastel .sidebar .sidebar-content .sidebar-btn {
background: #2563eb;
border: 0;
border-radius: 999px;
box-shadow: 0 4px 16px rgba(37, 99, 235, 0.12), 0 1px 2px rgba(0,0,0,0.04);
color: #fff;
}
.board-color-appleglasspastel button[type="submit"].primary:hover,
.board-color-appleglasspastel input[type="submit"].primary:hover,
.board-color-appleglasspastel button.primary:hover,
.board-color-appleglasspastel input.primary:hover {
background: #1d4ed8;
color: #fff;
}
.board-color-appleglasspastel input[type="email"],
.board-color-appleglasspastel input[type="password"],
.board-color-appleglasspastel input[type="text"],
.board-color-appleglasspastel textarea,
.board-color-appleglasspastel select {
background: rgba(255, 255, 255, 0.72);
border: 1px solid rgba(229, 231, 235, 0.9);
border-radius: 12px;
color: #111827;
}
.board-color-appleglasspastel input:focus,
.board-color-appleglasspastel textarea:focus,
.board-color-appleglasspastel select:focus {
border-color: #2563eb;
box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.12);
}
.board-color-appleglasspastel .materialCheckBox.is-checked {
border-bottom: 2px solid #2563eb;
border-inline-end: 2px solid #2563eb;
}
.board-color-appleglasspastel .checklist-progress-bar {
background-color: #dbeafe !important;
}
.board-color-appleglasspastel .checklist-progress-bar .checklist-progress {
background-color: #2563eb !important;
}
.board-color-appleglasspastel .is-multiselection-active .multi-selection-checkbox.is-checked + .minicard {
background: #eff6ff;
}
.board-color-appleglasspastel .is-multiselection-active .multi-selection-checkbox:not(.is-checked) + .minicard:hover:not(.minicard-composer) {
background: rgba(255, 255, 255, 0.88);
}
.board-color-appleglasspastel .toggle-label:after {
background-color: #2563eb;
}
.board-color-appleglasspastel .toggle-switch:checked ~ .toggle-label {
background-color: #93c5fd;
}
.board-color-appleglasspastel .toggle-switch:checked ~ .toggle-label:after {
background-color: #2563eb;
}
.board-color-appleglasspastel .card-date.current,
.board-color-appleglasspastel .minicard .current {
background: #1f7d38;
color: #fff !important;
}
.board-color-appleglasspastel .card-date.due,
.board-color-appleglasspastel .minicard .due {
background: #dc3545;
color: #fff !important;
}
.board-color-appleglasspastel .sidebar .sidebar-content {
scrollbar-color: rgba(37, 99, 235, 0.35) rgba(255, 255, 255, 0);
}
@media screen and (max-width: 800px) {
.board-color-appleglasspastel.pop-over .header {
background: #2563eb;
color: #fff;
}
}
/* === END Apple Glass Pastel THEME === */
/* ===============
THEME - Clear Blue
=================*/
@@ -365,6 +365,13 @@ Template.adminReports.helpers({
showDatabase() {
return Template.instance().showDatabase;
},
// Filesystem integrity. Without this helper the pane rendered NOTHING: the
// menu entry set tmpl.showIntegrity, the template asked for `showIntegrity.get`,
// and an undefined helper is simply falsy - so the branch never ran, the page
// was blank, and Summary went on counting the problems it could not show.
showIntegrity() {
return Template.instance().showIntegrity;
},
showCpu() {
return Template.instance().showCpu;
},
@@ -0,0 +1,60 @@
/* ── Admin Panel / Settings / Version ────────────────────────────────────────
ONE table, in five categories - Platform, OS, Meteor, Database, Node - where
each category is a row of its own that spans both columns.
WHY ONE TABLE. It was five, one per category, and five tables size their
columns independently: "WeKan ® Version" made the first one's label column
wide and "OS Type" made the next one's narrow, so the values started at a
different x in every group and the pane read as five unrelated things. One
table puts every label and every value in the same place. */
/* Two EQUAL columns, and they stay equal whatever the longest label happens to
be. `table-layout: fixed` makes the browser take the widths from the colgroup
instead of measuring the content, and the two `col` rules below are that
colgroup - written here rather than as inline width attributes so a theme can
override them in one place.
The `max-width: none` undoes settingBody.css's 240px cap on admin table
headers, which exists to stop a long label blowing a column up; here the
column width is stated outright, so the cap has nothing to protect and would
only fight the 50%. Both rules are scoped through .info-table, so no other
admin table is touched. */
.setting-content .content-body .main-body table.info-table {
table-layout: fixed;
}
.setting-content .content-body .main-body table.info-table > colgroup > col {
width: 50%;
}
.setting-content .content-body .main-body table.info-table th,
.setting-content .content-body .main-body table.info-table td {
max-width: none;
}
/* The category row. It spans both columns, so it is not a label with a value
beside it - it is a line that says what the rows under it are about.
BOLD and start-aligned, at the table's own font size: it names a group of rows
inside the pane, and the pane title above it (`.admin-pane-title`, 1.25rem)
names the pane. Growing these to that size would read as five pane titles and
"Version" would be lost among them. `color: inherit` for the same reason it is
on the pane title: the panel is themeable and a fixed colour goes unreadable
on a dark one. */
.setting-content .content-body .main-body table.info-table tr.info-category > th {
/* start, not left: a th centres by default, and this must sit over the label
column - which is the RIGHT edge in Arabic and Hebrew (tests/rtl.test.js). */
text-align: start;
font-weight: 700;
color: inherit;
/* Space above the group, none below it: the separation belongs BETWEEN
groups, and a gap under the title would push it away from the rows it
introduces. */
padding-top: 18px;
}
/* ...except the first one, which sits directly under the pane title and needs no
second gap on top of the 12px that title already brings. */
.setting-content .content-body .main-body table.info-table tr.info-category:first-child > th {
padding-top: 0;
}
+89 -40
View File
@@ -5,49 +5,45 @@
//- templates are global) inside the Settings page, which brings the left menu, the
//- pane title and the admin check with it. The /information URL redirects to
//- Settings, the same way the old /translation URL does.
//-
//- ONE table, in FIVE categories. This was a single flat list of 40 rows in which
//- the WeKan version, the OS load average, the DDP transport and a V8 heap counter
//- were the same kind of thing, read top to bottom, with no way to jump to the part
//- you came for. It is grouped now - what this IS (version and packaging), what it
//- runs ON, how Meteor is talking to the client, what the database is, and finally
//- Node's own memory - and each group is introduced by a row of its own that SPANS
//- BOTH COLUMNS, in bold.
//-
//- One table rather than five, because five tables size their columns
//- independently: "WeKan ® Version" made the first one's label column wide and
//- "OS Type" made the next one's narrow, so the values started at a different x
//- in every group and the pane read as five unrelated things. One table with a
//- colgroup of two 50% columns puts every label and every value in the same place
//- (.info-table in informationBody.css).
template(name='statistics')
table
table.info-table
//- Two equal columns, stated once here rather than left to the widest cell:
with table-layout fixed these are what the browser uses, so the labels and
the values line up down the whole pane no matter which group is longest.
colgroup
col
col
tbody
tr.info-category
th(colspan="2") {{_ 'Platform'}}
tr
th WeKan ® {{_ 'info'}}
td {{statistics.version}}
//- The LABEL is translated; the VALUE never is. bundle.zip, Snap, Docker
and Sandstorm are the names of the things themselves - a package
format, a store, a product - not words describing them, and a reader
reporting an issue, searching the docs or grepping a log needs the same
four strings in every language. See models/lib/platformPackaging.js.
tr
th {{_ 'Meteor_version'}}
td {{statistics.meteor.meteorVersion}}
tr
th {{_ 'Node_version'}}
td {{statistics.process.nodeVersion}}
tr
th {{_ 'Database_type'}}
td {{statistics.mongo.databaseType}}
tr
th {{_ 'MongoDB_version'}}
td {{statistics.mongo.mongoVersion}}
tr
th {{_ 'Database_commit'}}
td {{statistics.mongo.databaseCommit}}
if statistics.mongo.ferretdbVersion
tr
th {{_ 'FerretDB_version'}}
td {{statistics.mongo.ferretdbVersion}}
tr
th {{_ 'FerretDB_commit'}}
td {{statistics.mongo.ferretdbCommit}}
tr
th {{_ 'MongoDB_storage_engine'}}
td {{statistics.mongo.mongoStorageEngine}}
tr
th {{_ 'MongoDB_Oplog_enabled'}}
td {{formatBoolean statistics.mongo.mongoOplogEnabled}}
tr
th {{_ 'Reactivity_mode'}}
td {{statistics.mongo.reactivity}}
tr
th {{_ 'Reactivity_order'}}
td {{statistics.mongo.reactivityOrder}}
tr
th {{_ 'DDP_transport'}}
td {{statistics.mongo.ddpTransport}}
th {{_ 'package'}}
td {{statistics.platform.packaging}}
tr.info-category
th(colspan="2") {{_ 'OS'}}
tr
th {{_ 'OS_Type'}}
td {{statistics.os.type}}
@@ -75,6 +71,62 @@ template(name='statistics')
tr
th {{_ 'OS_Cpus'}}
td {{statistics.os.cpus.length}}
tr.info-category
th(colspan="2") {{_ 'Meteor'}}
tr
th {{_ 'Meteor_version'}}
td {{statistics.meteor.meteorVersion}}
//- Reactivity and DDP are Meteor's, not the database's: what is LIVE
(reactivity), what was ASKED for (reactivity order), and how the client
is connected (DDP transport). Whether an OpLog exists to tail is a
property of the database and stays in that table.
tr
th {{_ 'Reactivity_mode'}}
td {{statistics.mongo.reactivity}}
tr
th {{_ 'Reactivity_order'}}
td {{statistics.mongo.reactivityOrder}}
tr
th {{_ 'DDP_transport'}}
td {{statistics.mongo.ddpTransport}}
tr.info-category
th(colspan="2") {{_ 'Database'}}
tr
th {{_ 'Database_type'}}
td {{statistics.mongo.databaseType}}
tr
th {{_ 'MongoDB_version'}}
td {{statistics.mongo.mongoVersion}}
tr
th {{_ 'Database_commit'}}
td {{statistics.mongo.databaseCommit}}
//- Only when FerretDB is what answered: on MongoDB these two rows have
nothing to say, and an empty row reads as a missing value.
if statistics.mongo.ferretdbVersion
tr
th {{_ 'FerretDB_version'}}
td {{statistics.mongo.ferretdbVersion}}
tr
th {{_ 'FerretDB_commit'}}
td {{statistics.mongo.ferretdbCommit}}
tr
th {{_ 'MongoDB_storage_engine'}}
td {{statistics.mongo.mongoStorageEngine}}
tr
th {{_ 'MongoDB_Oplog_enabled'}}
td {{formatBoolean statistics.mongo.mongoOplogEnabled}}
unless isSandstorm
tr
th {{_ 'Mongo_sessions_count'}}
td {{statistics.session.sessionsCount}}
tr.info-category
th(colspan="2") {{_ 'Node'}}
tr
th {{_ 'Node_version'}}
td {{statistics.process.nodeVersion}}
//- A Sandstorm grain has no V8 heap figures collected for it (see
server/statistics.js), so the version above is all this table can say
there.
unless isSandstorm
tr
th {{_ 'Node_heap_total_heap_size'}}
@@ -121,6 +173,3 @@ template(name='statistics')
tr
th {{_ 'Node_memory_usage_external'}}
td {{fileSize statistics.nodeMemoryUsage.external}}
tr
th {{_ 'Mongo_sessions_count'}}
td {{statistics.session.sessionsCount}}
+1
View File
@@ -40,6 +40,7 @@ import '/client/components/settings/translationBody.js';
// forms.css and rendered with a black/grey background instead of the theme.
import '/client/components/settings/adminReports.css';
import '/client/components/settings/attachments.css';
import '/client/components/settings/informationBody.css';
import '/client/components/settings/lockedUsersBody.css';
import '/client/components/settings/migrationProgress.css';
import '/client/components/settings/peopleBody.css';
+1
View File
@@ -11,6 +11,7 @@ export const ALLOWED_BOARD_COLORS = [
'dark',
'relax',
'corteza',
'appleglasspastel',
'clearblue',
'cleargreen',
'clearorange',
+18 -2
View File
@@ -55,8 +55,24 @@ The compose files do not use a FerretDB image: a small Debian container download
the `ferretdb-<arch>` binary for its own architecture from the newest
[wekan/FerretDB release](https://github.com/wekan/FerretDB/releases), caches it on
the volume and runs it. Pin a version with `FERRETDB_RELEASE=download/v1.24.2`.
The same per-arch binaries are embedded in the WeKan bundles for the platforms
MongoDB has no server build for — ppc64le, s390x, riscv64.
**Seventeen of those binaries are built**, all cross-compiled from one checkout
with CGO disabled: ten Linux (`amd64`, `arm64`, `armhf`, `armv6`, `armel`,
`i386`, `ppc64le`, `s390x`, `riscv64`, `loong64`), three Windows (`win64`,
`win-arm64`, `win32`), two macOS (`mac-amd64`, `mac-arm64`) and two FreeBSD
(`freebsd-amd64`, `freebsd-arm64`). The 32-bit ARM ones are three different
builds, not three names for one: `armhf` is `GOARM=7`, `armv6` is `GOARM=6` for
the Raspberry Pi 1 and Zero, and `armel` is `GOARM=5` software floating point for
genuine ARMv5.
A `ferretdb-<arch>` binary is embedded in **every** WeKan bundle, and it is the
default database on the platforms MongoDB publishes no server for — ppc64le,
s390x, riscv64, i386, armv6 and armhf — where nothing else can be. There is also
a multi-arch image (`wekanteam/ferretdb`, `quay.io/wekan/ferretdb`,
`ghcr.io/wekan/ferretdb`) built `FROM scratch` around these same binaries, which
is why it covers every Linux one of them, including `linux/arm/v6` and
`linux/loong64` that the WeKan image cannot reach — see
[Docker CPU platforms](../../../Platforms/FOSS/Container/Docker/CPU-platforms.md).
The `hana` handler is behind the `ferretdb_hana` build tag; the released binaries
are built with it, so `--handler=hana` exists. A FerretDB built elsewhere without
+1 -1
View File
@@ -43,7 +43,7 @@ Files in this directory are served by meteor as-is to the client. It hosts some
* **[popup.tpl.jade](../../client/components/main/popup.tpl.jade)**: tpl files only define a single template so there's no need to wrap content in a template tag; the name of the template is the base name of the file (`popup` in this case);
* **[spinner.tpl.jade](https://github.com/wekan/wekan/tree/main/client/components/main/spinner.tpl.jade)**: is the template for a "waiting" dialog;
* **[settings](../../client/components/settings)**:
* **[informationBody.jade](../../client/components/settings/informationBody.jade)**: `information`, `statistics` templates;
* **[informationBody.jade](../../client/components/settings/informationBody.jade)**: the `statistics` template — the Version pane of Admin Panel / Settings, five tables (Platform, OS, Meteor, Database, Node). There is no `information` template any more: it is a pane rendered by `settingBody.jade`, not a page;
* **[invitationCode.jade](../../client/components/settings/invitationCode.jade)**: `invitationCode` template;
* **[peopleBody.jade](../../client/components/settings/peopleBody.jade)**: `people`, `peopleGeneral`, `peopleRow`, `editUserPopup`;
* **[settingBody.jade](../../client/components/settings/settingBody.jade)**: `setting`, `general`, `email`, `accountSettings`, `announcementSettings`
@@ -0,0 +1,210 @@
# WeKan Docker image — CPU platforms
This page documents, **for the WeKan Docker image**, which CPU platforms the
multi-arch manifest carries, how that set is decided on every release, which
database each platform starts by default, and which bundle platforms are
deliberately not images.
The snap has the same page of its own:
[Snap CPU platforms](../Snap/CPU-platforms.md).
## Summary
- **The image is assembled from the release bundles, not compiled per platform.**
`Dockerfile` downloads `wekan-<version>-<arch>.zip` from the GitHub Release for
the platform it is building, installs a Node.js resolved by
[`releases/resolve-node-source.sh`](../../../../../releases/resolve-node-source.sh)
— the same script the bundles and the snap use, so one architecture's image and
bundle always carry the same Node.js from the same source — and runs the
bundle. There is no per-platform compile in the image at all.
- **At most eight Linux platforms.** `linux/amd64` and `linux/arm64` are
**required**; `linux/ppc64le`, `linux/s390x`, `linux/riscv64`, `linux/386`,
`linux/arm/v6` and `linux/arm/v7` are **optional** and included only when their
bundle landed on the release **and** the base image publishes the platform.
- **A missing optional bundle drops only itself.** One failed extra-arch build
removes that platform from the manifest with a warning; it does not fail or
skip the Docker job, and the platform comes back on the next release that
builds it.
- **`linux/arm/v6` is a candidate that drops itself today**, because
`debian:trixie` publishes `arm/v5` and `arm/v7` and nothing between them. See
[armv6](#armv6-wired-end-to-end-waiting-on-a-base-image) — this is the one
platform whose absence is not about WeKan at all.
- **Three registries, two tags each**: `wekanteam/wekan`, `quay.io/wekan/wekan`
and `ghcr.io/wekan/wekan`, at `:v<version>` and `:latest`, built with
`--provenance=mode=max` and verified after the push by asking each registry
what it actually has.
- **Not image platforms:** loong64 (no base image exists), armv6, armv7, and
every Windows and macOS bundle. Each has a reason below, and none of them is an
oversight.
## Per-platform matrix
| Docker platform | `TARGETARCH` | `TARGETVARIANT` | Bundle | Required | Database when nothing is set |
|-----------------|--------------|-----------------|--------|:--------:|------------------------------|
| `linux/amd64` | `amd64` | — | `amd64` | ✅ | external MongoDB (`MONGO_URL`) |
| `linux/arm64` | `arm64` | (`v8`, implied) | `arm64` | ✅ | external MongoDB (`MONGO_URL`) |
| `linux/ppc64le` | `ppc64le` | — | `ppc64le` | ❌ | bundled FerretDB v1 (SQLite) |
| `linux/s390x` | `s390x` | — | `s390x` | ❌ | bundled FerretDB v1 (SQLite) |
| `linux/riscv64` | `riscv64` | — | `riscv64` | ❌ | bundled FerretDB v1 (SQLite) |
| `linux/386` | `386` | — | `i386` | ❌ | bundled FerretDB v1 (SQLite) |
| `linux/arm/v6` | `arm` | `v6` | `armv6` | ❌ | bundled FerretDB v1 (SQLite) |
| `linux/arm/v7` | `arm` | `v7` or unset | `armhf` | ❌ | bundled FerretDB v1 (SQLite) |
**`TARGETARCH` alone does not identify a platform.** ARMv6 and ARMv7 both arrive
as `arm`; only `TARGETVARIANT` tells them apart, which is why the `Dockerfile`'s
architecture `case` branches on the pair. Mapping `arm` straight to `armhf`, as
it did before, would hand a Raspberry Pi 1 the ARMv7-A bundle. `v5` (armel) is
refused outright rather than falling through: Go builds ARMv5, Node.js does not
exist for it, so there is no bundle to put in an image.
**Required** means the Docker job fails if that bundle is not on the release:
without amd64 and arm64 there is no image worth pushing, and a release that got
that far would already have failed.
**The database column is a default, not a limit.** Every bundle carries a
`ferretdb` binary, so FerretDB v1 runs on every platform; the default is decided
by [`releases/ferretdb/wekan-entrypoint.sh`](../../../../../releases/ferretdb/wekan-entrypoint.sh)
from a `/build/.ferretdb-default` marker that every extra-architecture bundle
carries and the amd64/arm64 bundles have removed. `WEKAN_DB=ferretdb` or
`WEKAN_DB=mongodb` overrides it on any platform, and setting `MONGO_URL` on a
FerretDB-default platform points WeKan at that database instead.
## How the platform set is decided, on every release
The `docker` job in
[`.github/workflows/release-all.yml`](../../../../../.github/workflows/release-all.yml)
does this before it builds anything:
1. It holds two lists — `req="linux/amd64:amd64 linux/arm64:arm64"` and
`opt="linux/ppc64le:ppc64le linux/s390x:s390x linux/riscv64:riscv64
linux/386:i386 linux/arm/v6:armv6 linux/arm/v7:armhf"` — where each entry is
*docker platform : the bundle arch the Dockerfile downloads for it*.
2. It asks the **base image** which platforms it publishes
(`docker buildx imagetools inspect`, with the base name read out of the
`Dockerfile` so there is no second copy of it), and drops any candidate the
base lacks.
3. It asks the **release**, with an HTTP `HEAD`, whether
`wekan-<version>-<arch>.zip` is there.
A missing **required** base platform or bundle is an error; a missing
**optional** one is a warning and that platform is dropped. The chosen set then
drives all three of the buildx `--platform` list, the wait-for-the-assets loop,
and the post-push verification — so the three can never disagree about what the
image was supposed to contain.
**Why the base is asked at all**, when a missing base would surely just fail the
build: for 32-bit ARM it does not fail. containerd treats a **lower** ARM variant
as compatible, so a `linux/arm/v6` request against a base that has `arm/v5` and
`arm/v7` resolves to `arm/v5` — Debian **armel**, soft-float — and an image built
on that would carry a hard-float `node-armv6` its own loader cannot start. A
silent downgrade is worse than a dropped platform, so it is dropped, loudly,
with the reason in the warning.
`tests/releaseDockerPlatforms.test.cjs` pins that shape: which platforms are
required, which are optional, that `linux/loong64` is never among them, that
every platform resolves to the bundle the Decide step paired it with, that the
`arm` branch reads `TARGETVARIANT` and refuses `v5`, and that both loops check
the base.
## The names, and the ones that do not match
An architecture is spelled one way by Docker, another by Debian, and a third by
the WeKan bundles. Three of them differ here:
| Docker | `TARGETARCH` | WeKan bundle | Note |
|--------|--------------|--------------|------|
| `linux/386` | `386` | `i386` | everyone but Docker and Node.js says i386 |
| `linux/arm/v7` | `arm` | `armhf` | Debian's 32-bit ARM port: ARMv7-A, VFPv3-D16 |
| `linux/arm64` | `arm64` | `arm64` | buildx reports it as `linux/arm64/v8`; the verify step strips the implied `/v8` |
The `Dockerfile` maps `TARGETARCH` to the bundle name in one `case` and **exits
on anything it does not know**, rather than guessing — an unrecognised platform
would otherwise download another CPU's `.zip` and produce an image that starts
and then dies.
## What is not an image platform, and why
### loong64 — there is no base image to build on
`node-loong64` and `ferretdb-loong64` both exist and the bundle is built, but no
Docker base image publishes loong64 at any tag — not debian, not ubuntu — so
there is no loong64 userland to install into, and the registries do not agree on
what the platform is even called. `tests/releaseDockerPlatforms.test.cjs`
asserts `linux/loong64` is not in the platform list, so this stays a decision
rather than something that quietly reappears.
### armv6 — wired end to end, waiting on a base image
ARMv6 (Raspberry Pi 1 and Zero) is a **candidate platform**: `linux/arm/v6` is in
the optional list, the `Dockerfile` resolves it to the `armv6` bundle through
`TARGETVARIANT`, and the guard test pins both. Everything the image needs exists —
`node-armv6` from [wekan/node-patches](https://github.com/wekan/node-patches)
(nobody else publishes an ARMv6 Node.js) and `GOARM=6` binaries from
[wekan/FerretDB](https://github.com/wekan/FerretDB) and
[wekan/mongo-tools-patches](https://github.com/wekan/mongo-tools-patches).
**What is missing is a base image.** `debian:trixie`'s manifest list is `386`,
`amd64`, `arm64/v8`, `arm/v5`, `arm/v7`, `ppc64le`, `riscv64`, `s390x` — there is
no `arm/v6`. Debian has no ARMv6 port: its 32-bit ARM ports are armel (ARMv5,
soft-float) and armhf (ARMv7-A). ARMv6 hard-float is Raspberry Pi OS territory,
not Debian's. So the release drops the platform with a warning and the image
ships without it, while the **armv6 bundle zip is unaffected** — that is how an
ARMv6 board runs WeKan today.
The day the base publishes `arm/v6`, or the base for that one platform becomes an
ARMv6 userland, the platform is included automatically: nothing else has to
change. Until then, do **not** "fix" this by removing the base check — that is
what makes the drop a warning instead of an image whose Node.js cannot start.
`models/lib/snapArchitectures.js` describes armv6 as shipping "a bundle zip and a
`linux/arm/v6` Docker image"; the bundle is real today, the image is prepared and
gated.
### armv7 — one 32-bit ARM slot, and it carries the baseline
There is one `linux/arm/v7` platform, and it must run on any ARMv7-A board, so it
carries the **armhf** bundle: the `armv7` bundle assumes NEON, which is an
illegal instruction on an ARMv7-A board without it. This is the same reasoning
that gives armv7 no snap — see
[the snap page](../Snap/CPU-platforms.md#armhf-and-armv7-are-the-same-cpu-family-built-to-different-baselines).
### win64, win32, win-arm64, mac-x64, mac-arm64
Bundle platforms that are not Linux. They are not container images and are not
expected to be.
## Variant images
[`docker-variant.yml`](../../../../../.github/workflows/docker-variant.yml)
publishes the variant repositories, **manually and never as part of a release**.
It rebuilds nothing: `docker buildx imagetools create` copies the *manifest*, so
a variant tag points at the very digests the release built and verified, and can
never drift from `wekanteam/wekan`. Before and after the retag it checks that
`linux/amd64`, `linux/arm64`, `linux/ppc64le`, `linux/s390x` and `linux/riscv64`
are all present, so a variant cannot silently cover fewer architectures than
`wekan` does. `releases/docker-publish-variant.sh` is the same thing locally.
## The FerretDB image covers more platforms than the WeKan image
[wekan/FerretDB](https://github.com/wekan/FerretDB)'s own `docker.yml` builds
`FROM scratch` around the **prebuilt** per-architecture Go binaries, with no
QEMU and no base image, so a platform costs it nothing but a binary. Its manifest
is computed from whichever `ferretdb-<arch>` assets downloaded, mapping
`amd64`→`linux/amd64`, `arm64`→`linux/arm64`, `armhf`→`linux/arm/v7`,
`armv6`→`linux/arm/v6`, `armel`→`linux/arm/v5`, `i386`→`linux/386`,
`ppc64le`→`linux/ppc64le`, `s390x`→`linux/s390x`, `riscv64`→`linux/riscv64` and
`loong64`→`linux/loong64`. It is published as `wekanteam/ferretdb`,
`quay.io/wekan/ferretdb` and `ghcr.io/wekan/ferretdb`.
That is why the two lists differ: the WeKan image needs a Debian userland and a
Node.js for a platform, and the FerretDB image needs only one static binary.
## Related
- [Snap CPU platforms](../Snap/CPU-platforms.md) — the same page for the snap
- [Which compose file, which database](README.md)
- [FerretDB v1 and its backends](../../../../Databases/FerretDB/1/)
- The platform list in code: the `docker` job of
[`release-all.yml`](../../../../../.github/workflows/release-all.yml), guarded by
`tests/releaseDockerPlatforms.test.cjs`
- Node.js per platform: [wekan/node-patches](https://github.com/wekan/node-patches)
@@ -1,3 +1,6 @@
Which CPU platforms the image is published for, and why some bundle platforms are
not images: [CPU-platforms.md](CPU-platforms.md).
## WeKan Docker compose files (which database?)
Since the default database changed, the compose files in https://github.com/wekan/wekan are:
@@ -10,8 +10,8 @@ and how the one-time MongoDB 3 → FerretDB v1 migration works.
FerretDB v1 is the wekan/FerretDB fork with an embedded pure-Go SQLite backend
that speaks the MongoDB wire protocol, so WeKan talks to it exactly like MongoDB.
- **Six architectures are built as snaps**: amd64, arm64, armhf, ppc64el, riscv64
and s390x — exactly `snapcraft.yaml`'s `build-for:` list. i386 and armv7 are
release bundles but **not** snaps, for reasons that are not oversights; see
and s390x — exactly `snapcraft.yaml`'s `build-for:` list. i386, armv6 and armv7
are release bundles but **not** snaps, for reasons that are not oversights; see
[CPU architecture names](#cpu-architecture-names-and-what-they-mean).
- **MongoDB 7 *server* binaries (mongod) are included for amd64 and arm64 only.**
The other architectures (armhf, ppc64el, riscv64, s390x) have no MongoDB server
@@ -91,6 +91,32 @@ the `armhf` bundle, and **`armv7` has no snap** — it ships as a bundle only. A
separate snap name or track would be the only way to offer the NEON build, which
is not worth a second listing for one board family.
### armv6 has no snap, because the store has no such architecture
ARMv6 is the Raspberry Pi 1 and the Pi Zero: 32-bit ARM with **VFPv2** hardware
floating point and **no NEON**. The Snap Store's only 32-bit ARM architecture is
`armhf`, which is the **ARMv7-A** hard-float baseline — an ARMv6 board cannot run
an armhf snap, and there is no armv6 architecture to publish one as. So there is
nothing to fix here and nothing to add: **armv6 ships as a release bundle zip**,
and nothing else in the Snap Store. (It is a candidate platform of the Docker
image too, gated on a base image that publishes `linux/arm/v6` — see
[Docker CPU platforms](../Docker/CPU-platforms.md#armv6-wired-end-to-end-waiting-on-a-base-image).)
It is a separate build from armhf all the way down, not a re-tag of it:
[wekan/node-patches](https://github.com/wekan/node-patches) builds `node-armv6`
(`--with-arm-fpu=vfp`, `-march=armv6+fp`) because nobody publishes an ARMv6
Node.js any more — nodejs.org dropped it after Node 11 —
and [wekan/FerretDB](https://github.com/wekan/FerretDB) and
[wekan/mongo-tools-patches](https://github.com/wekan/mongo-tools-patches) build
`GOARM=6` binaries beside their armhf ones. Their `armel` (`GOARM=5`) would run
on an ARMv6 board, which is what makes it look like a substitute: it does
floating point in **software**, so it is not one.
`models/lib/snapArchitectures.js` records this reason in
`NOT_SNAP_ARCHITECTURES`, beside i386's and armv7's, and
`tests/releaseSnapArches.test.cjs` asserts armv6 is neither a snap platform nor a
Launchpad build.
### i386 has no snap, and cannot have a new one
core24 is Ubuntu 24.04, which has **no i386 port**, so there is no i386 core24
@@ -107,11 +133,24 @@ version `0.X-ci`) because the store keeps whatever was ever uploaded. It is year
stale, nothing new can be built for it, and re-releasing it would only re-publish
`0.X-ci`. **i386 users are served by the .deb and the AppImage.**
### loong64, win64, win32, mac-x64, mac-arm64
### loong64, win64, win32, win-arm64, mac-x64, mac-arm64
Bundle platforms with no Snap Store architecture at all. They are not snaps and
are not expected to be.
### The whole bundle list, and which of it is a snap
The release builds fifteen bundles; six of them become snaps. The rest are
bundles (and, for some, Docker images) only:
| Bundle | Snap? | Why not |
|--------|-------|---------|
| `amd64`, `arm64`, `armhf`, `ppc64le` (→ `ppc64el`), `riscv64`, `s390x` | ✅ | — |
| `armv6` | ❌ | the store has no armv6 architecture |
| `armv7` | ❌ | the store's one 32-bit ARM slot must carry the armhf baseline |
| `i386` | ❌ | core24 has no i386 port |
| `loong64`, `win64`, `win32`, `win-arm64`, `mac-x64`, `mac-arm64` | ❌ | no Snap Store architecture at all |
## New installs
On a fresh install, every architecture starts on **FerretDB v1 (SQLite)** with
@@ -183,6 +222,73 @@ After a successful migration the snap switches to `database=ferretdb`.
Architectures other than amd64 ship no MongoDB server and no MongoDB 3 client, so
there is nothing to migrate from — they are FerretDB v1 from the first boot.
### Which MongoDB databases the snap can migrate from
**Three readers, on amd64 and arm64.** A MongoDB server only starts on data whose
`featureCompatibilityVersion` is at most one major behind it, so which versions
can be read is a property of which servers the snap carries:
| Reader | Opens data from | Used for |
|--------|-----------------|----------|
| mongod 7 (the server it runs) | MongoDB 6.0, 7.0 | the running database, and reading a 6/7 one to migrate |
| **mongod 4.2** (migration only) | MongoDB 4.0, 4.2 | reading a 4.x database to migrate |
| the MongoDB 3.2 tools (`migratemongo`) | MongoDB 3.2 | reading a 6.09-era database to migrate |
mongod 4.2 is bundled for **amd64 and arm64 only** — MongoDB publishes no 4.2 for
the others, and they have been FerretDB from their first boot, so there is nothing
there to migrate from. It carries its own OpenSSL 1.1, because core24 ships
OpenSSL 3 and the 4.2 build will not load without 1.1. It is used **only to read**
during a migration; the running database is never mongod 4.2.
What is still unreadable, therefore: **3.4, 3.6, 4.4 and 5.0**. A database from
one of those gets the page below rather than a migration.
### A database from a MongoDB none of the three can read
A database left by a **MongoDB 4.4 or 5.0** snap (or a 3.4/3.6 one) opens in none
of them — mongod 7 refuses it with
```
This version of MongoDB is too recent to start up on the existing data files.
Try MongoDB 4.2 or earlier.
```
and neither mongod 4.2 nor the 3.2 tools can open them either. Reading those
files needs a server the snap does not carry, so **no retry can succeed**, and
there is nothing the snap can migrate from.
What it does instead of trying: it **stops**, writes
`$SNAP_COMMON/.mongodb-data-too-old` with the version mongod itself named as
still able to read the data, and serves an explanatory page on the web port
instead of 502. MongoDB is not started (a start that cannot work would be
restarted by snapd forever, and used to bounce between mongod and the migration
three times before giving up), auto-migration is paused, and **nothing is
changed**: the database files, the attachments and the avatars are exactly as
they were.
Two ways forward, both keeping the data:
1. **Go back to the revision that worked** and stay there for now:
```
sudo snap revert wekan
sudo snap refresh --hold=forever wekan
```
2. **Move the data across** with a MongoDB that can read it (the version the page
names): start that MongoDB on the data directory, `mongodump` from it, restore
the dump into this version, and let the MongoDB → FerretDB migration above run.
Attachments and avatars are **files on disk**, not database rows, so they are
unaffected either way — see `$SNAP_COMMON/files`.
To let the snap try again — after moving the data, say — remove the marker:
```
sudo rm /var/snap/wekan/common/.mongodb-data-too-old
sudo snap restart wekan
```
## Where the FerretDB v1 binary comes from
FerretDB v1 is built and released separately in
@@ -263,22 +369,35 @@ publishes edge builds to stable users. Pass the version, or `--dry-run` first.
### What each snap currently has, and what is still to add
As of WeKan 10.76 the store holds:
As of WeKan **10.78** the store holds:
| Snap | amd64 | arm64 | armhf | ppc64el | riscv64 | s390x |
|------|:-----:|:-----:|:-----:|:-------:|:-------:|:-----:|
| `wekan` | ✅ | ✅ | — | ✅ | — | ✅ |
| `wekan-ondra` | ✅ | ✅ | ⚠️ | — | — | — |
| `wekan-gantt-gpl` | ✅ | ✅ | — | — | — | — |
| `wekan` | ✅ 10.78 | ✅ 10.78 | ❌ | ✅ 10.78 | ✅ 10.78 | ✅ 10.78 |
| `wekan-ondra` | ✅ 10.78 | ✅ 10.78 | ⚠️ 0.22 | 🚫 | 🚫 | 🚫 |
| `wekan-gantt-gpl` | ✅ 10.78 | ✅ 10.78 | 🚫 | 🚫 | 🚫 | 🚫 |
- **—** the architecture is built by `snapcraft.yaml` but that snap has no
revision for it yet. Uploading one is all that is needed; the release script
then puts it on all four channels.
- **⚠️** `wekan-ondra`'s armhf is stuck at version **0.22**, and its i386 column at
**0.X-ci**, on all four channels — fossils the store kept from years ago.
Promoting channels cannot fix these: there is no newer revision to promote.
armhf needs a build uploaded for that snap; i386 cannot be built at all (see
[i386](#i386-has-no-snap-and-cannot-have-a-new-one)).
`wekan-ondra` also shows an **i386** column at `0.X-ci`; nothing builds it and
nothing can (see [i386](#i386-has-no-snap-and-cannot-have-a-new-one)).
The three marks mean three different things, and the difference is the whole
point of the table:
- **❌ built by the release, not in the store.** `wekan`'s armhf is the only one:
`snapcraft.yaml` declares it, the `snap-launchpad` job builds it, and it has
been failing — most recently on Caddy, which publishes no `linux_armhf` archive
because its asset names are Go's. That is fixed for the next release. Nothing
to do here but release.
- **🚫 the release does not build it for that snap at all.** The `snap-variants`
job that publishes `wekan-ondra` and `wekan-gantt-gpl` has FOUR matrix entries —
each variant on amd64 and on arm64, on GitHub runners. The exotic architectures
come from `snap-launchpad`, which builds only the `wekan` name. So no upload is
pending for these squares: they need the variant job extended to Launchpad
remote builds under the variant snap names first.
- **⚠️ a fossil.** `wekan-ondra`'s armhf is stuck at version **0.22** on all four
channels — a revision the store kept from years ago. Promoting channels cannot
fix it: there is no newer revision to promote, and per the row above nothing
currently builds one.
Publishing the **stable** channel is safe for these because the snap performs its
**automatic migrations** on start — the schema upgrades and the one-time
@@ -288,6 +407,8 @@ manual step.
## Related
- [Docker CPU platforms](../Docker/CPU-platforms.md) — the same page for the
Docker image, which has a different platform list and different reasons
- FerretDB v1 fork: https://github.com/wekan/FerretDB
- Snap install: [Install.md](Install.md)
- Snap settings keys: [Supported-settings-keys.md](Supported-settings-keys.md)
@@ -10,7 +10,7 @@ This is without container (without Docker or Snap).
Right click and download files 1-4:
1. [wekan-10.78-win64.zip](https://github.com/wekan/wekan/releases/download/v10.78/wekan-10.78-win64.zip) or newest available at https://github.com/wekan/wekan/releases/
1. [wekan-10.80-win64.zip](https://github.com/wekan/wekan/releases/download/v10.80/wekan-10.80-win64.zip) or newest available at https://github.com/wekan/wekan/releases/
2. [node.exe](https://nodejs.org/dist/latest-v24.x/win-x64/node.exe)
@@ -22,7 +22,7 @@ Right click and download files 1-4:
6. Double click `mongodb-windows-x86_64-7.0.34-signed.msi` . In installer, uncheck downloading MongoDB compass.
7. Unzip `wekan-10.78-win64.zip` , inside it is directory `bundle`, to it copy other files:
7. Unzip `wekan-10.80-win64.zip` , inside it is directory `bundle`, to it copy other files:
```
bundle (directory)
+7 -7
View File
@@ -4,11 +4,11 @@ Status: **Core implemented · picker UI design** · Owner: xet7 · Related: #577
per-user theme), Board Settings / Change Color, Member Settings / Change Color, #5514
(the native color-wheel `<input type="color">` already used for list colors).
WeKan ships ~19 board theme colors. Many are near-duplicates that differ only by **one or
two accent colors**; a few (`clearblue`) are **two-color "color slides"** (gradients). This
document defines how the **Select Color** picker — used in **both** Board Settings and
Member Settings (the global override) — is reorganized into **categories** with **two-level
dropdowns** and **custom colors** where it makes sense.
WeKan ships named board theme colors. Many are near-duplicates that differ only by **one
or two accent colors**; the `clear*` themes are **two-color "color slides"** (gradients).
This document defines how the **Select Color** picker — used in **both** Board Settings
and Member Settings (the global override) — is reorganized into **categories** with
**two-level dropdowns** and **custom colors** where it makes sense.
## 1. Categories
@@ -19,9 +19,9 @@ The colors partition into four categories (single source of truth:
| Category | Colors | Custom colors |
|----------|--------|---------------|
| **flat** | belize, nephritis, pomegranate, pumpkin, wisteria, moderatepink, strongcyan, limegreen, natural | **1** (single accent) |
| **clear** | clearblue | **2** (color slide / gradient) |
| **clear** | clearblue, cleargreen, clearorange, clearpink, clearpurple, clearred | **2** (color slide / gradient) |
| **dark** | midnight, dark, moderndark, exodark, cleandark | **none** (fixed) |
| **special** | relax, corteza, modern, cleanlight | **none** (fixed) |
| **special** | relax, corteza, appleglasspastel, modern, cleanlight | **none** (fixed) |
Rationale: **flat** designs are one accent color over a flat surface, so a single custom color
fully re-skins them. **clear** designs are a two-color gradient ("slide"), so they take two
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Cangkuk Web Global",
"new-outgoing-webhook": "Cangkuk Web Keluar Baru",
"no-name": "(Tidak Diketahui)",
"Platform": "Platform",
"package": "Package",
"OS": "OS",
"Meteor": "Meteor",
"Database": "Pangkalan data",
"Node": "Node",
"Node_version": "Versi Node",
"Meteor_version": "Versi Meteor",
"Database_type": "Tipe database",
@@ -2339,5 +2345,8 @@
"event-severity": "Keuparah",
"event-action": "Tindakan",
"event-source": "Sumber",
"event-detail": "Rincian"
}
"event-detail": "Rincian",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Globale Webhooks",
"new-outgoing-webhook": "Nuwe Uitgaande Webhook",
"no-name": "(Onbekend)",
"Platform": "Platform",
"package": "Pakket",
"OS": "Bedryfstelsel",
"Meteor": "Meteor",
"Database": "Databasis",
"Node": "Node",
"Node_version": "Node weergawe",
"Meteor_version": "Meteoor weergawe",
"Database_type": "Databasistipe",
@@ -2339,5 +2345,8 @@
"event-severity": "Erns",
"event-action": "Aksie",
"event-source": "Bron",
"event-detail": "Besonderhede"
}
"event-detail": "Besonderhede",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Globale Webhooks",
"new-outgoing-webhook": "Nuwe Uitgaande Webhook",
"no-name": "(Onbekend)",
"Platform": "Platform",
"package": "Pakket",
"OS": "Bedryfstelsel",
"Meteor": "Meteor",
"Database": "Databasis",
"Node": "Node",
"Node_version": "Node weergawe",
"Meteor_version": "Meteoor weergawe",
"Database_type": "Databasistipe",
@@ -2339,5 +2345,8 @@
"event-severity": "Erns",
"event-action": "Aksie",
"event-source": "Bron",
"event-detail": "Besonderhede"
}
"event-detail": "Besonderhede",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "وب‌هوک‌های سراسری",
"new-outgoing-webhook": "ويبهوك جديدة",
"no-name": "(غير معروف)",
"Platform": "المنصة",
"package": "الحزمة",
"OS": "نظام التشغيل",
"Meteor": "Meteor",
"Database": "قاعدة البيانات",
"Node": "Node",
"Node_version": "إصدار النود",
"Meteor_version": "نسخه متئور",
"Database_type": "نوع قاعدة البيانات",
@@ -2339,5 +2345,8 @@
"event-severity": "الخطورة",
"event-action": "الإجراء",
"event-source": "المصدر",
"event-detail": "التفاصيل"
}
"event-detail": "التفاصيل",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "وب‌هوک‌های سراسری",
"new-outgoing-webhook": "ويبهوك جديدة",
"no-name": "(غير معروف)",
"Platform": "المنصة",
"package": "الحزمة",
"OS": "نظام التشغيل",
"Meteor": "Meteor",
"Database": "قاعدة البيانات",
"Node": "Node",
"Node_version": "إصدار النود",
"Meteor_version": "نسخه متئور",
"Database_type": "نوع قاعدة البيانات",
@@ -2339,5 +2345,8 @@
"event-severity": "الخطورة",
"event-action": "الإجراء",
"event-source": "المصدر",
"event-detail": "التفاصيل"
}
"event-detail": "التفاصيل",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "وب‌هوک‌های سراسری",
"new-outgoing-webhook": "ويبهوك جديدة",
"no-name": "(غير معروف)",
"Platform": "المنصة",
"package": "الحزمة",
"OS": "نظام التشغيل",
"Meteor": "Meteor",
"Database": "قاعدة البيانات",
"Node": "Node",
"Node_version": "إصدار النود",
"Meteor_version": "نسخه متئور",
"Database_type": "نوع قاعدة البيانات",
@@ -2339,5 +2345,8 @@
"event-severity": "الخطورة",
"event-action": "الإجراء",
"event-source": "المصدر",
"event-detail": "التفاصيل"
}
"event-detail": "التفاصيل",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "وب‌هوک‌های سراسری",
"new-outgoing-webhook": "ويبهوك جديدة",
"no-name": "(غير معروف)",
"Platform": "Platform",
"package": "Package",
"OS": "OS",
"Meteor": "Meteor",
"Database": "قاعدة البيانات",
"Node": "Node",
"Node_version": "إصدار النود",
"Meteor_version": "نسخه متئور",
"Database_type": "نوع قاعدة البيانات",
@@ -2339,5 +2345,8 @@
"event-severity": "الخطورة",
"event-action": "الإجراء",
"event-source": "المصدر",
"event-detail": "التفاصيل"
}
"event-detail": "التفاصيل",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Webhooks globales",
"new-outgoing-webhook": "Nuevo webhook saliente",
"no-name": "(Desconocido)",
"Platform": "Plataforma",
"package": "Paquete",
"OS": "Sistema operativu",
"Meteor": "Meteor",
"Database": "Base de datos",
"Node": "Node",
"Node_version": "Versión de Node",
"Meteor_version": "Versión de Meteor",
"Database_type": "Triba de base de datos",
@@ -2339,5 +2345,8 @@
"event-severity": "Gravedá",
"event-action": "Aición",
"event-source": "Fonte",
"event-detail": "Detalle"
}
"event-detail": "Detalle",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Qlobal Webhooks",
"new-outgoing-webhook": "Yeni Gedən Webhook",
"no-name": "(Naməlum)",
"Platform": "Platforma",
"package": "Paket",
"OS": "Əməliyyat sistemi",
"Meteor": "Meteor",
"Database": "Verilənlər bazası",
"Node": "Node",
"Node_version": "Node versiyası",
"Meteor_version": "Meteor versiyası",
"Database_type": "Verilənlər bazası növü",
@@ -2339,5 +2345,8 @@
"event-severity": "Ciddilik",
"event-action": "Əməliyyat",
"event-source": "Mənbə",
"event-detail": "Təfərrüat"
}
"event-detail": "Təfərrüat",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Qlobal Webhooks",
"new-outgoing-webhook": "Yeni Gedən Webhook",
"no-name": "(Naməlum)",
"Platform": "Platforma",
"package": "Paket",
"OS": "Əməliyyat sistemi",
"Meteor": "Meteor",
"Database": "Verilənlər bazası",
"Node": "Node",
"Node_version": "Node versiyası",
"Meteor_version": "Meteor versiyası",
"Database_type": "Verilənlər bazası növü",
@@ -2339,5 +2345,8 @@
"event-severity": "Ciddilik",
"event-action": "Əməliyyat",
"event-source": "Mənbə",
"event-detail": "Təfərrüat"
}
"event-detail": "Təfərrüat",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Qlobal Webhooks",
"new-outgoing-webhook": "Yeni Gedən Webhook",
"no-name": "(Naməlum)",
"Platform": "Platforma",
"package": "Paket",
"OS": "Əməliyyat sistemi",
"Meteor": "Meteor",
"Database": "Verilənlər bazası",
"Node": "Node",
"Node_version": "Node versiyası",
"Meteor_version": "Meteor versiyası",
"Database_type": "Verilənlər bazası növü",
@@ -2339,5 +2345,8 @@
"event-severity": "Ciddilik",
"event-action": "Əməliyyat",
"event-source": "Mənbə",
"event-detail": "Təfərrüat"
}
"event-detail": "Təfərrüat",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Глабальныя вэб-хукі",
"new-outgoing-webhook": "Новы выходны вэб-хук",
"no-name": "(Невядома)",
"Platform": "Платформа",
"package": "Пакет",
"OS": "АС",
"Meteor": "Meteor",
"Database": "База даных",
"Node": "Node",
"Node_version": "Версія Node",
"Meteor_version": "Версія Meteor",
"Database_type": "Тып базы дадзеных",
@@ -2339,5 +2345,8 @@
"event-severity": "Сур'ёзнасць",
"event-action": "Дзеянне",
"event-source": "Крыніца",
"event-detail": "Дэталі"
}
"event-detail": "Дэталі",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Глобални Webhooks",
"new-outgoing-webhook": "Нов Изходящ Webhook",
"no-name": "(Непознат)",
"Platform": "Платформа",
"package": "Пакет",
"OS": "ОС",
"Meteor": "Meteor",
"Database": "База данни",
"Node": "Node",
"Node_version": "Версия на Node",
"Meteor_version": "Версия на Meteor",
"Database_type": "Тип на базата данни",
@@ -2339,5 +2345,8 @@
"event-severity": "Сериозност",
"event-action": "Действие",
"event-source": "Източник",
"event-detail": "Детайл"
}
"event-detail": "Детайл",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Webhooks globaux",
"new-outgoing-webhook": "Nouveau webhook sortant",
"no-name": "(Inconnu)",
"Platform": "Platform",
"package": "Package",
"OS": "OS",
"Meteor": "Meteor",
"Database": "Diaz roadennoù",
"Node": "Node",
"Node_version": "Version de Node",
"Meteor_version": "Version de Meteor",
"Database_type": "Rizh ar bank-roadennoù",
@@ -2339,5 +2345,8 @@
"event-severity": "Garvder",
"event-action": "Ober",
"event-source": "Mammenn",
"event-detail": "Munud"
}
"event-detail": "Munud",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Webhooks globals",
"new-outgoing-webhook": "Nou Webbook sortt",
"no-name": "Importa tauler des de Wekan",
"Platform": "Plataforma",
"package": "Paquet",
"OS": "Sistema operatiu",
"Meteor": "Meteor",
"Database": "Base de dades",
"Node": "Node",
"Node_version": "Versió Node",
"Meteor_version": "Versió Meteor",
"Database_type": "Tipus de base de dades",
@@ -2339,5 +2345,8 @@
"event-severity": "Gravetat",
"event-action": "Acció",
"event-source": "Origen",
"event-detail": "Detall"
}
"event-detail": "Detall",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Webhooks globals",
"new-outgoing-webhook": "Nou Webbook sortt",
"no-name": "Importa tauler des de Wekan",
"Platform": "Plataforma",
"package": "Paquet",
"OS": "Sistema operatiu",
"Meteor": "Meteor",
"Database": "Base de dades",
"Node": "Node",
"Node_version": "Versió Node",
"Meteor_version": "Versió Meteor",
"Database_type": "Tipus de base de dades",
@@ -2339,5 +2345,8 @@
"event-severity": "Gravetat",
"event-action": "Acció",
"event-source": "Origen",
"event-detail": "Detall"
}
"event-detail": "Detall",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Webhooks globals",
"new-outgoing-webhook": "Nou Webbook sortt",
"no-name": "Importa tauler des de Wekan",
"Platform": "Plataforma",
"package": "Paquet",
"OS": "Sistema operatiu",
"Meteor": "Meteor",
"Database": "Base de dades",
"Node": "Node",
"Node_version": "Versió Node",
"Meteor_version": "Versió Meteor",
"Database_type": "Tipus de base de dades",
@@ -2339,5 +2345,8 @@
"event-severity": "Gravetat",
"event-action": "Acció",
"event-source": "Origen",
"event-detail": "Detall"
}
"event-detail": "Detall",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "全局 Webhooks",
"new-outgoing-webhook": "新的传出 Webhook",
"no-name": "(未知)",
"Platform": "平台",
"package": "软件包",
"OS": "操作系统",
"Meteor": "Meteor",
"Database": "数据库",
"Node": "Node",
"Node_version": "节点版本",
"Meteor_version": "流星版",
"Database_type": "数据库类型",
@@ -2339,5 +2345,8 @@
"event-severity": "严重程度",
"event-action": "操作",
"event-source": "来源",
"event-detail": "详情"
}
"event-detail": "详情",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Globální webhooks",
"new-outgoing-webhook": "Nové odchozí Webhooky",
"no-name": "(Neznámé)",
"Platform": "Platforma",
"package": "Balíček",
"OS": "OS",
"Meteor": "Meteor",
"Database": "Databáze",
"Node": "Node",
"Node_version": "Node verze",
"Meteor_version": "Verze Meteor",
"Database_type": "Typ databáze",
@@ -2339,5 +2345,8 @@
"event-severity": "Závažnost",
"event-action": "Akce",
"event-source": "Zdroj",
"event-detail": "Detail"
}
"event-detail": "Detail",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Globální webhooks",
"new-outgoing-webhook": "Nové odchozí Webhooky",
"no-name": "(Neznámé)",
"Platform": "Platforma",
"package": "Balíček",
"OS": "OS",
"Meteor": "Meteor",
"Database": "Databáze",
"Node": "Node",
"Node_version": "Node verze",
"Meteor_version": "Verze Meteor",
"Database_type": "Typ databáze",
@@ -2339,5 +2345,8 @@
"event-severity": "Závažnost",
"event-action": "Akce",
"event-source": "Zdroj",
"event-detail": "Detail"
}
"event-detail": "Detail",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Bachau Gwe Byd-eang",
"new-outgoing-webhook": "Llyfr Gwe Allan Newydd",
"no-name": "(Anhysbys)",
"Platform": "Platfform",
"package": "Pecyn",
"OS": "System gweithredu",
"Meteor": "Meteor",
"Database": "Cronfa ddata",
"Node": "Node",
"Node_version": "Fersiwn nod",
"Meteor_version": "Fersiwn Meteor",
"Database_type": "Math o gronfa ddata",
@@ -2339,5 +2345,8 @@
"event-severity": "Difrifoldeb",
"event-action": "Gweithred",
"event-source": "Ffynhonnell",
"event-detail": "Manylion"
}
"event-detail": "Manylion",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Bachau Gwe Byd-eang",
"new-outgoing-webhook": "Llyfr Gwe Allan Newydd",
"no-name": "(Anhysbys)",
"Platform": "Platfform",
"package": "Pecyn",
"OS": "System gweithredu",
"Meteor": "Meteor",
"Database": "Cronfa ddata",
"Node": "Node",
"Node_version": "Fersiwn nod",
"Meteor_version": "Fersiwn Meteor",
"Database_type": "Math o gronfa ddata",
@@ -2339,5 +2345,8 @@
"event-severity": "Difrifoldeb",
"event-action": "Gweithred",
"event-source": "Ffynhonnell",
"event-detail": "Manylion"
}
"event-detail": "Manylion",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Globale webhooks",
"new-outgoing-webhook": "Ny udgående webhook",
"no-name": "(Ukendt)",
"Platform": "Platform",
"package": "Pakke",
"OS": "OS",
"Meteor": "Meteor",
"Database": "Database",
"Node": "Node",
"Node_version": "Node-version",
"Meteor_version": "Meteor-version",
"Database_type": "Databasetype",
@@ -2339,5 +2345,8 @@
"event-severity": "Alvorsgrad",
"event-action": "Handling",
"event-source": "Kilde",
"event-detail": "Detalje"
}
"event-detail": "Detalje",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Globale Webhooks",
"new-outgoing-webhook": "Neuer ausgehender Webhook",
"no-name": "(Unbekannt)",
"Platform": "Plattform",
"package": "Paket",
"OS": "Betriebssystem",
"Meteor": "Meteor",
"Database": "Datenbank",
"Node": "Node",
"Node_version": "Node-Version",
"Meteor_version": "Meteor-Version",
"Database_type": "Datenbanktyp",
@@ -2339,5 +2345,8 @@
"event-severity": "Schweregrad",
"event-action": "Aktion",
"event-source": "Quelle",
"event-detail": "Detail"
}
"event-detail": "Detail",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Globale Webhooks",
"new-outgoing-webhook": "Neuer ausgehender Webhook",
"no-name": "(Unbekannt)",
"Platform": "Plattform",
"package": "Paket",
"OS": "Betriebssystem",
"Meteor": "Meteor",
"Database": "Datenbank",
"Node": "Node",
"Node_version": "Node-Version",
"Meteor_version": "Meteor-Version",
"Database_type": "Datenbanktyp",
@@ -2339,5 +2345,8 @@
"event-severity": "Schweregrad",
"event-action": "Aktion",
"event-source": "Quelle",
"event-detail": "Detail"
}
"event-detail": "Detail",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Globale Webhooks",
"new-outgoing-webhook": "Neuer ausgehender Webhook",
"no-name": "(Unbekannt)",
"Platform": "Plattform",
"package": "Paket",
"OS": "Betriebssystem",
"Meteor": "Meteor",
"Database": "Datenbank",
"Node": "Node",
"Node_version": "Node-Version",
"Meteor_version": "Meteor-Version",
"Database_type": "Datenbanktyp",
@@ -2339,5 +2345,8 @@
"event-severity": "Schweregrad",
"event-action": "Aktion",
"event-source": "Quelle",
"event-detail": "Detail"
}
"event-detail": "Detail",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Globale Webhooks",
"new-outgoing-webhook": "Neuer ausgehender Webhook",
"no-name": "(Unbekannt)",
"Platform": "Plattform",
"package": "Paket",
"OS": "Betriebssystem",
"Meteor": "Meteor",
"Database": "Datenbank",
"Node": "Node",
"Node_version": "Node-Version",
"Meteor_version": "Meteor-Version",
"Database_type": "Datenbanktyp",
@@ -2339,5 +2345,8 @@
"event-severity": "Schweregrad",
"event-action": "Aktion",
"event-source": "Quelle",
"event-detail": "Detail"
}
"event-detail": "Detail",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Webhook globali",
"new-outgoing-webhook": "Νέο Εξερχόμενο Webhook",
"no-name": "(Άγνωστο)",
"Platform": "Πλατφόρμα",
"package": "Πακέτο",
"OS": "Λειτουργικό σύστημα",
"Meteor": "Meteor",
"Database": "Βάση δεδομένων",
"Node": "Node",
"Node_version": "Έκδοση Node",
"Meteor_version": "Έκδοση Meteor",
"Database_type": "Τύπος βάσης δεδομένων",
@@ -2339,5 +2345,8 @@
"event-severity": "Σοβαρότητα",
"event-action": "Ενέργεια",
"event-source": "Πηγή",
"event-detail": "Λεπτομέρεια"
}
"event-detail": "Λεπτομέρεια",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Webhook globali",
"new-outgoing-webhook": "Νέο Εξερχόμενο Webhook",
"no-name": "(Άγνωστο)",
"Platform": "Πλατφόρμα",
"package": "Πακέτο",
"OS": "Λειτουργικό σύστημα",
"Meteor": "Meteor",
"Database": "Βάση δεδομένων",
"Node": "Node",
"Node_version": "Έκδοση Node",
"Meteor_version": "Έκδοση Meteor",
"Database_type": "Τύπος βάσης δεδομένων",
@@ -2339,5 +2345,8 @@
"event-severity": "Σοβαρότητα",
"event-action": "Ενέργεια",
"event-source": "Πηγή",
"event-detail": "Λεπτομέρεια"
}
"event-detail": "Λεπτομέρεια",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Global Webhooks",
"new-outgoing-webhook": "New Outgoing Webhook",
"no-name": "(Unknown)",
"Platform": "Platform",
"package": "Package",
"OS": "OS",
"Meteor": "Meteor",
"Database": "Database",
"Node": "Node",
"Node_version": "Node version",
"Meteor_version": "Meteor version",
"Database_type": "Database type",
@@ -2339,5 +2345,8 @@
"event-severity": "Severity",
"event-action": "Action",
"event-source": "Source",
"event-detail": "Detail"
}
"event-detail": "Detail",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Global Webhooks",
"new-outgoing-webhook": "New Outgoing Webhook",
"no-name": "(Unknown)",
"Platform": "Platform",
"package": "Package",
"OS": "OS",
"Meteor": "Meteor",
"Database": "Database",
"Node": "Node",
"Node_version": "Node version",
"Meteor_version": "Meteor version",
"Database_type": "Database type",
@@ -2339,5 +2345,8 @@
"event-severity": "Severity",
"event-action": "Action",
"event-source": "Source",
"event-detail": "Detail"
}
"event-detail": "Detail",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Global Webhooks",
"new-outgoing-webhook": "New Outgoing Webhook",
"no-name": "(Unknown)",
"Platform": "Platform",
"package": "Package",
"OS": "OS",
"Meteor": "Meteor",
"Database": "Database",
"Node": "Node",
"Node_version": "Node version",
"Meteor_version": "Meteor version",
"Database_type": "Database type",
@@ -2339,5 +2345,8 @@
"event-severity": "Severity",
"event-action": "Action",
"event-source": "Source",
"event-detail": "Detail"
}
"event-detail": "Detail",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Global Webhooks",
"new-outgoing-webhook": "New Outgoing Webhook",
"no-name": "(Unknown)",
"Platform": "Platform",
"package": "Package",
"OS": "OS",
"Meteor": "Meteor",
"Database": "Database",
"Node": "Node",
"Node_version": "Node version",
"Meteor_version": "Meteor version",
"Database_type": "Database type",
@@ -2339,5 +2345,8 @@
"event-severity": "Severity",
"event-action": "Action",
"event-source": "Source",
"event-detail": "Detail"
}
"event-detail": "Detail",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Global Webhooks",
"new-outgoing-webhook": "New Outgoing Webhook",
"no-name": "(Unknown)",
"Platform": "Platform",
"package": "Package",
"OS": "OS",
"Meteor": "Meteor",
"Database": "Database",
"Node": "Node",
"Node_version": "Node version",
"Meteor_version": "Meteor version",
"Database_type": "Database type",
@@ -2339,5 +2345,8 @@
"event-severity": "Severity",
"event-action": "Action",
"event-source": "Source",
"event-detail": "Detail"
}
"event-detail": "Detail",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Global Webhooks",
"new-outgoing-webhook": "New Outgoing Webhook",
"no-name": "(Unknown)",
"Platform": "Platform",
"package": "Package",
"OS": "OS",
"Meteor": "Meteor",
"Database": "Database",
"Node": "Node",
"Node_version": "Node version",
"Meteor_version": "Meteor version",
"Database_type": "Database type",
@@ -2339,5 +2345,8 @@
"event-severity": "Severity",
"event-action": "Action",
"event-source": "Source",
"event-detail": "Detail"
}
"event-detail": "Detail",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+6
View File
@@ -949,6 +949,12 @@
"global-webhook": "Global Webhooks",
"new-outgoing-webhook": "New Outgoing Webhook",
"no-name": "(Unknown)",
"Platform": "Platform",
"package": "Package",
"OS": "OS",
"Meteor": "Meteor",
"Database": "Database",
"Node": "Node",
"Node_version": "Node version",
"Meteor_version": "Meteor version",
"Database_type": "Database type",
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Global Webhooks",
"new-outgoing-webhook": "New Outgoing Webhook",
"no-name": "(Unknown)",
"Platform": "Platform",
"package": "Package",
"OS": "OS",
"Meteor": "Meteor",
"Database": "Database",
"Node": "Node",
"Node_version": "Node version",
"Meteor_version": "Meteor version",
"Database_type": "Database type",
@@ -2339,5 +2345,8 @@
"event-severity": "Severity",
"event-action": "Action",
"event-source": "Source",
"event-detail": "Detail"
}
"event-detail": "Detail",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Global Webhooks",
"new-outgoing-webhook": "New Outgoing Webhook",
"no-name": "(Unknown)",
"Platform": "Platform",
"package": "Package",
"OS": "OS",
"Meteor": "Meteor",
"Database": "Database",
"Node": "Node",
"Node_version": "Node version",
"Meteor_version": "Meteor version",
"Database_type": "Database type",
@@ -2339,5 +2345,8 @@
"event-severity": "Severity",
"event-action": "Action",
"event-source": "Source",
"event-detail": "Detail"
}
"event-detail": "Detail",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Global Webhooks",
"new-outgoing-webhook": "New Outgoing Webhook",
"no-name": "(Unknown)",
"Platform": "Platform",
"package": "Package",
"OS": "OS",
"Meteor": "Meteor",
"Database": "Database",
"Node": "Node",
"Node_version": "Node version",
"Meteor_version": "Meteor version",
"Database_type": "Database type",
@@ -2339,5 +2345,8 @@
"event-severity": "Severity",
"event-action": "Action",
"event-source": "Source",
"event-detail": "Detail"
}
"event-detail": "Detail",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Global Webhooks",
"new-outgoing-webhook": "New Outgoing Webhook",
"no-name": "(Unknown)",
"Platform": "Platform",
"package": "Package",
"OS": "OS",
"Meteor": "Meteor",
"Database": "Database",
"Node": "Node",
"Node_version": "Node version",
"Meteor_version": "Meteor version",
"Database_type": "Database type",
@@ -2339,5 +2345,8 @@
"event-severity": "Severity",
"event-action": "Action",
"event-source": "Source",
"event-detail": "Detail"
}
"event-detail": "Detail",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Global Webhooks",
"new-outgoing-webhook": "New Outgoing Webhook",
"no-name": "(Unknown)",
"Platform": "Platform",
"package": "Package",
"OS": "OS",
"Meteor": "Meteor",
"Database": "Database",
"Node": "Node",
"Node_version": "Node version",
"Meteor_version": "Meteor version",
"Database_type": "Database type",
@@ -2339,5 +2345,8 @@
"event-severity": "Severity",
"event-action": "Action",
"event-source": "Source",
"event-detail": "Detail"
}
"event-detail": "Detail",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Webhooks globales",
"new-outgoing-webhook": "Nuevo webhook saliente",
"no-name": "(Desconocido)",
"Platform": "Platformo",
"package": "Pakaĵo",
"OS": "Mastruma sistemo",
"Meteor": "Meteor",
"Database": "Datumbazo",
"Node": "Node",
"Node_version": "Versión de Node",
"Meteor_version": "Versión de Meteor",
"Database_type": "Datumbaza tipo",
@@ -2339,5 +2345,8 @@
"event-severity": "Graveco",
"event-action": "Ago",
"event-source": "Fonto",
"event-detail": "Detalo"
}
"event-detail": "Detalo",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Webhooks globales",
"new-outgoing-webhook": "Nuevo Gancho Web",
"no-name": "(desconocido)",
"Platform": "Plataforma",
"package": "Paquete",
"OS": "Sistema operativo",
"Meteor": "Meteor",
"Database": "Base de datos",
"Node": "Node",
"Node_version": "Versión de Node",
"Meteor_version": "Versión de Meteor",
"Database_type": "Tipo de base de datos",
@@ -2339,5 +2345,8 @@
"event-severity": "Gravedad",
"event-action": "Acción",
"event-source": "Origen",
"event-detail": "Detalle"
}
"event-detail": "Detalle",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Webhooks globales",
"new-outgoing-webhook": "Nuevo webhook saliente",
"no-name": "(Desconocido)",
"Platform": "Plataforma",
"package": "Paquete",
"OS": "Sistema operativo",
"Meteor": "Meteor",
"Database": "Base de datos",
"Node": "Node",
"Node_version": "Versión de Node",
"Meteor_version": "Versión de Meteor",
"Database_type": "Tipo de base de datos",
@@ -2339,5 +2345,8 @@
"event-severity": "Gravedad",
"event-action": "Acción",
"event-source": "Origen",
"event-detail": "Detalle"
}
"event-detail": "Detalle",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Webhooks globales",
"new-outgoing-webhook": "Nuevo webhook saliente",
"no-name": "(Desconocido)",
"Platform": "Plataforma",
"package": "Paquete",
"OS": "Sistema operativo",
"Meteor": "Meteor",
"Database": "Base de datos",
"Node": "Node",
"Node_version": "Versión de Node",
"Meteor_version": "Versión de Meteor",
"Database_type": "Tipo de base de datos",
@@ -2339,5 +2345,8 @@
"event-severity": "Gravedad",
"event-action": "Acción",
"event-source": "Origen",
"event-detail": "Detalle"
}
"event-detail": "Detalle",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Webhooks globales",
"new-outgoing-webhook": "Nuevo webhook saliente",
"no-name": "(Desconocido)",
"Platform": "Plataforma",
"package": "Paquete",
"OS": "Sistema operativo",
"Meteor": "Meteor",
"Database": "Base de datos",
"Node": "Node",
"Node_version": "Versión de Node",
"Meteor_version": "Versión de Meteor",
"Database_type": "Tipo de base de datos",
@@ -2339,5 +2345,8 @@
"event-severity": "Gravedad",
"event-action": "Acción",
"event-source": "Origen",
"event-detail": "Detalle"
}
"event-detail": "Detalle",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Webhooks globales",
"new-outgoing-webhook": "Nuevo webhook saliente",
"no-name": "(Desconocido)",
"Platform": "Plataforma",
"package": "Paquete",
"OS": "Sistema operativo",
"Meteor": "Meteor",
"Database": "Base de datos",
"Node": "Node",
"Node_version": "Versión de Node",
"Meteor_version": "Versión de Meteor",
"Database_type": "Tipo de base de datos",
@@ -2339,5 +2345,8 @@
"event-severity": "Gravedad",
"event-action": "Acción",
"event-source": "Origen",
"event-detail": "Detalle"
}
"event-detail": "Detalle",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Webhooks globales",
"new-outgoing-webhook": "Nuevo webhook saliente",
"no-name": "(Desconocido)",
"Platform": "Plataforma",
"package": "Paquete",
"OS": "Sistema operativo",
"Meteor": "Meteor",
"Database": "Base de datos",
"Node": "Node",
"Node_version": "Versión de Node",
"Meteor_version": "Versión de Meteor",
"Database_type": "Tipo de base de datos",
@@ -2339,5 +2345,8 @@
"event-severity": "Gravedad",
"event-action": "Acción",
"event-source": "Origen",
"event-detail": "Detalle"
}
"event-detail": "Detalle",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Webhooks globales",
"new-outgoing-webhook": "Nuevo webhook saliente",
"no-name": "(Desconocido)",
"Platform": "Plataforma",
"package": "Paquete",
"OS": "Sistema operativo",
"Meteor": "Meteor",
"Database": "Base de datos",
"Node": "Node",
"Node_version": "Versión de Node",
"Meteor_version": "Versión de Meteor",
"Database_type": "Tipo de base de datos",
@@ -2339,5 +2345,8 @@
"event-severity": "Gravedad",
"event-action": "Acción",
"event-source": "Origen",
"event-detail": "Detalle"
}
"event-detail": "Detalle",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Webhooks globales",
"new-outgoing-webhook": "Nuevo webhook saliente",
"no-name": "(Desconocido)",
"Platform": "Plataforma",
"package": "Paquete",
"OS": "Sistema operativo",
"Meteor": "Meteor",
"Database": "Base de datos",
"Node": "Node",
"Node_version": "Versión de Node",
"Meteor_version": "Versión de Meteor",
"Database_type": "Tipo de base de datos",
@@ -2339,5 +2345,8 @@
"event-severity": "Gravedad",
"event-action": "Acción",
"event-source": "Origen",
"event-detail": "Detalle"
}
"event-detail": "Detalle",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Globaalsed veebikonksud",
"new-outgoing-webhook": "Uus väljaminev veebikonks",
"no-name": "(Tundmatu)",
"Platform": "Platvorm",
"package": "Pakett",
"OS": "Operatsioonisüsteem",
"Meteor": "Meteor",
"Database": "Andmebaas",
"Node": "Node",
"Node_version": "Sõlme versioon",
"Meteor_version": "Meteori versioon",
"Database_type": "Andmebaasi tüüp",
@@ -2339,5 +2345,8 @@
"event-severity": "Raskusaste",
"event-action": "Toiming",
"event-source": "Allikas",
"event-detail": "Üksikasjad"
}
"event-detail": "Üksikasjad",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Webhooks globales",
"new-outgoing-webhook": "Irteera-webhook berria",
"no-name": "(Ezezaguna)",
"Platform": "Plataforma",
"package": "Paketea",
"OS": "Sistema eragilea",
"Meteor": "Meteor",
"Database": "Datu-basea",
"Node": "Node",
"Node_version": "Nodo bertsioa",
"Meteor_version": "Meteor bertsioa",
"Database_type": "Datu-base mota",
@@ -2339,5 +2345,8 @@
"event-severity": "Larritasuna",
"event-action": "Ekintza",
"event-source": "Iturria",
"event-detail": "Xehetasuna"
}
"event-detail": "Xehetasuna",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "وب‌هوک‌های سراسری",
"new-outgoing-webhook": "ويبهوك جديدة",
"no-name": "(ناشناخته)",
"Platform": "سکو",
"package": "بسته",
"OS": "سیستم‌عامل",
"Meteor": "Meteor",
"Database": "پایگاه داده",
"Node": "Node",
"Node_version": "نسخه Node",
"Meteor_version": "نسخه متئور",
"Database_type": "نوع پایگاه داده",
@@ -2339,5 +2345,8 @@
"event-severity": "شدت",
"event-action": "اقدام",
"event-source": "منبع",
"event-detail": "جزئیات"
}
"event-detail": "جزئیات",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "وب‌هوک‌های سراسری",
"new-outgoing-webhook": "ويبهوك جديدة",
"no-name": "(ناشناخته)",
"Platform": "سکو",
"package": "بسته",
"OS": "سیستم‌عامل",
"Meteor": "Meteor",
"Database": "پایگاه داده",
"Node": "Node",
"Node_version": "نسخه Node",
"Meteor_version": "نسخه متئور",
"Database_type": "نوع پایگاه داده",
@@ -2339,5 +2345,8 @@
"event-severity": "شدت",
"event-action": "اقدام",
"event-source": "منبع",
"event-detail": "جزئیات"
}
"event-detail": "جزئیات",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Kaikenkattavat Webkoukut",
"new-outgoing-webhook": "Uusi lähtevä Webkoukku",
"no-name": "(Tuntematon)",
"Platform": "Alusta",
"package": "Paketti",
"OS": "Käyttöjärjestelmä",
"Meteor": "Meteor",
"Database": "Tietokanta",
"Node": "Node",
"Node_version": "Node-versio",
"Meteor_version": "Meteor-versio",
"Database_type": "Tietokannan tyyppi",
@@ -2339,5 +2345,8 @@
"event-severity": "Vakavuus",
"event-action": "Toiminto",
"event-source": "Lähde",
"event-detail": "Tiedot"
}
"event-detail": "Tiedot",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Webhooks globaux",
"new-outgoing-webhook": "Nouveau webhook sortant",
"no-name": "(Inconnu)",
"Platform": "Plate-forme",
"package": "Paquet",
"OS": "OS",
"Meteor": "Meteor",
"Database": "Base de données",
"Node": "Node",
"Node_version": "Version de Node",
"Meteor_version": "Version de Meteor",
"Database_type": "Type de base de données",
@@ -2339,5 +2345,8 @@
"event-severity": "Gravité",
"event-action": "Action",
"event-source": "Source",
"event-detail": "Détail"
}
"event-detail": "Détail",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Webhooks globaux",
"new-outgoing-webhook": "Nouveau webhook sortant",
"no-name": "(Inconnu)",
"Platform": "Plate-forme",
"package": "Paquet",
"OS": "OS",
"Meteor": "Meteor",
"Database": "Base de données",
"Node": "Node",
"Node_version": "Version de Node",
"Meteor_version": "Version de Meteor",
"Database_type": "Type de base de données",
@@ -2339,5 +2345,8 @@
"event-severity": "Gravité",
"event-action": "Action",
"event-source": "Source",
"event-detail": "Détail"
}
"event-detail": "Détail",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Webhooks globaux",
"new-outgoing-webhook": "Nouveau webhook sortant",
"no-name": "(Inconnu)",
"Platform": "Plate-forme",
"package": "Paquet",
"OS": "OS",
"Meteor": "Meteor",
"Database": "Base de données",
"Node": "Node",
"Node_version": "Version de Node",
"Meteor_version": "Version de Meteor",
"Database_type": "Type de base de données",
@@ -2339,5 +2345,8 @@
"event-severity": "Gravité",
"event-action": "Action",
"event-source": "Source",
"event-detail": "Détail"
}
"event-detail": "Détail",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Globale webhooks",
"new-outgoing-webhook": "Nije útgeande webhook",
"no-name": "(Ûnbekend)",
"Platform": "Platfoarm",
"package": "Pakket",
"OS": "Bestjoeringssysteem",
"Meteor": "Meteor",
"Database": "Database",
"Node": "Node",
"Node_version": "Node ferzje",
"Meteor_version": "Meteor ferzje",
"Database_type": "Databasetype",
@@ -2339,5 +2345,8 @@
"event-severity": "Earnst",
"event-action": "Aksje",
"event-source": "Boarne",
"event-detail": "Detail"
}
"event-detail": "Detail",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Globale webhooks",
"new-outgoing-webhook": "Nije útgeande webhook",
"no-name": "(Ûnbekend)",
"Platform": "Platfoarm",
"package": "Pakket",
"OS": "Bestjoeringssysteem",
"Meteor": "Meteor",
"Database": "Database",
"Node": "Node",
"Node_version": "Node ferzje",
"Meteor_version": "Meteor ferzje",
"Database_type": "Databasetype",
@@ -2339,5 +2345,8 @@
"event-severity": "Earnst",
"event-action": "Aksje",
"event-source": "Boarne",
"event-detail": "Detail"
}
"event-detail": "Detail",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Webhooks Globais",
"new-outgoing-webhook": "Novo Webhook de saída",
"no-name": "(Desconhecido)",
"Platform": "Plataforma",
"package": "Paquete",
"OS": "Sistema operativo",
"Meteor": "Meteor",
"Database": "Base de datos",
"Node": "Node",
"Node_version": "Versão do Node",
"Meteor_version": "Versão do Meteor",
"Database_type": "Tipo de base de datos",
@@ -2339,5 +2345,8 @@
"event-severity": "Gravidade",
"event-action": "Acción",
"event-source": "Orixe",
"event-detail": "Detalle"
}
"event-detail": "Detalle",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Webhooks Globais",
"new-outgoing-webhook": "Novo Webhook de saída",
"no-name": "(Desconhecido)",
"Platform": "Plataforma",
"package": "Paquete",
"OS": "Sistema operativo",
"Meteor": "Meteor",
"Database": "Base de datos",
"Node": "Node",
"Node_version": "Versão do Node",
"Meteor_version": "Versão do Meteor",
"Database_type": "Tipo de base de datos",
@@ -2339,5 +2345,8 @@
"event-severity": "Gravidade",
"event-action": "Acción",
"event-source": "Orixe",
"event-detail": "Detalle"
}
"event-detail": "Detalle",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "વૈશ્વિક વેબહુક્સ",
"new-outgoing-webhook": "નવું આઉટગોઇંગ વેબહૂક",
"no-name": "(અજ્ઞાત)",
"Platform": "Platform",
"package": "Package",
"OS": "OS",
"Meteor": "Meteor",
"Database": "ડેટાબેઝ",
"Node": "Node",
"Node_version": "નોડ સંસ્કરણ",
"Meteor_version": "ઉલ્કા સંસ્કરણ",
"Database_type": "ડેટાબેઝ પ્રકાર",
@@ -2339,5 +2345,8 @@
"event-severity": "ગંભીરતા",
"event-action": "ક્રિયા",
"event-source": "સ્રોત",
"event-detail": "વિગત"
}
"event-detail": "વિગત",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "התליות גלובליות",
"new-outgoing-webhook": "קרסי רשת יוצאים חדשים",
"no-name": "(לא ידוע)",
"Platform": "פלטפורמה",
"package": "חבילה",
"OS": "מערכת הפעלה",
"Meteor": "Meteor",
"Database": "מסד נתונים",
"Node": "Node",
"Node_version": "גרסת Node",
"Meteor_version": "גרסת Meteor",
"Database_type": "סוג מסד נתונים",
@@ -2339,5 +2345,8 @@
"event-severity": "חומרה",
"event-action": "פעולה",
"event-source": "מקור",
"event-detail": "פרט"
}
"event-detail": "פרט",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "התליות גלובליות",
"new-outgoing-webhook": "קרסי רשת יוצאים חדשים",
"no-name": "(לא ידוע)",
"Platform": "פלטפורמה",
"package": "חבילה",
"OS": "מערכת הפעלה",
"Meteor": "Meteor",
"Database": "מסד נתונים",
"Node": "Node",
"Node_version": "גרסת Node",
"Meteor_version": "גרסת Meteor",
"Database_type": "סוג מסד נתונים",
@@ -2339,5 +2345,8 @@
"event-severity": "חומרה",
"event-action": "פעולה",
"event-source": "מקור",
"event-detail": "פרט"
}
"event-detail": "פרט",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "વૈશ્વિક વેબહુક્સ",
"new-outgoing-webhook": "નવું આઉટગોઇંગ વેબહૂક",
"no-name": "(અજ્ઞાત)",
"Platform": "प्लेटफ़ॉर्म",
"package": "पैकेज",
"OS": "ऑपरेटिंग सिस्टम",
"Meteor": "Meteor",
"Database": "डेटाबेस",
"Node": "Node",
"Node_version": "નોડ સંસ્કરણ",
"Meteor_version": "ઉલ્કા સંસ્કરણ",
"Database_type": "डेटाबेस प्रकार",
@@ -2339,5 +2345,8 @@
"event-severity": "गंभीरता",
"event-action": "क्रिया",
"event-source": "स्रोत",
"event-detail": "विवरण"
}
"event-detail": "विवरण",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "વૈશ્વિક વેબહુક્સ",
"new-outgoing-webhook": "નવું આઉટગોઇંગ વેબહૂક",
"no-name": "(અજ્ઞાત)",
"Platform": "प्लेटफ़ॉर्म",
"package": "पैकेज",
"OS": "ऑपरेटिंग सिस्टम",
"Meteor": "Meteor",
"Database": "डेटाबेस",
"Node": "Node",
"Node_version": "નોડ સંસ્કરણ",
"Meteor_version": "ઉલ્કા સંસ્કરણ",
"Database_type": "डेटाबेस प्रकार",
@@ -2339,5 +2345,8 @@
"event-severity": "गंभीरता",
"event-action": "क्रिया",
"event-source": "स्रोत",
"event-detail": "विवरण"
}
"event-detail": "विवरण",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Дојава догађаја",
"new-outgoing-webhook": "Нова дојава догађаја",
"no-name": "(Nepoznato)",
"Platform": "Platforma",
"package": "Paket",
"OS": "OS",
"Meteor": "Meteor",
"Database": "Baza podataka",
"Node": "Node",
"Node_version": "Node inačica",
"Meteor_version": "Meteor inačica",
"Database_type": "Vrsta baze podataka",
@@ -2339,5 +2345,8 @@
"event-severity": "Ozbiljnost",
"event-action": "Radnja",
"event-source": "Izvor",
"event-detail": "Pojedinost"
}
"event-detail": "Pojedinost",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Globális webhurkok",
"new-outgoing-webhook": "Új kimenő webhurok",
"no-name": "(Ismeretlen)",
"Platform": "Platform",
"package": "Csomag",
"OS": "Operációs rendszer",
"Meteor": "Meteor",
"Database": "Adatbázis",
"Node": "Node",
"Node_version": "Node verzió",
"Meteor_version": "Meteor verzió",
"Database_type": "Adatbázis típusa",
@@ -2339,5 +2345,8 @@
"event-severity": "Súlyosság",
"event-action": "Művelet",
"event-source": "Forrás",
"event-detail": "Részlet"
}
"event-detail": "Részlet",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Համաշխարհային վեբ-կեռիկներ",
"new-outgoing-webhook": "Նոր ելքային Webhook",
"no-name": "(Անհայտ)",
"Platform": "Հարթակ",
"package": "Փաթեթ",
"OS": "Օպերացիոն համակարգ",
"Meteor": "Meteor",
"Database": "Տվյալների բազա",
"Node": "Node",
"Node_version": "Հանգույցի տարբերակը",
"Meteor_version": "Երկնաքարի տարբերակ",
"Database_type": "Տվյալների բազայի տեսակ",
@@ -2339,5 +2345,8 @@
"event-severity": "Լրջություն",
"event-action": "Գործողություն",
"event-source": "Աղբյուր",
"event-detail": "Մանրամասն"
}
"event-detail": "Մանրամասն",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Cangkuk Web Global",
"new-outgoing-webhook": "Cangkuk Web Keluar Baru",
"no-name": "(Tidak Diketahui)",
"Platform": "Platform",
"package": "Paket",
"OS": "Sistem operasi",
"Meteor": "Meteor",
"Database": "Basis data",
"Node": "Node",
"Node_version": "Versi Node",
"Meteor_version": "Versi Meteor",
"Database_type": "Tipe database",
@@ -2339,5 +2345,8 @@
"event-severity": "Tingkat keparahan",
"event-action": "Tindakan",
"event-source": "Sumber",
"event-detail": "Rincian"
}
"event-detail": "Rincian",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Global Webhooks",
"new-outgoing-webhook": "Webhook ọhụrụ na-apụ apụ",
"no-name": "(Amaghị)",
"Platform": "Platform",
"package": "Package",
"OS": "OS",
"Meteor": "Meteor",
"Database": "Ebe nchekwa data",
"Node": "Node",
"Node_version": "Ụdị ọnụ",
"Meteor_version": "Ụdị meteor",
"Database_type": "Ụdị Database",
@@ -2339,5 +2345,8 @@
"event-severity": "Ịdị njọ",
"event-action": "Omume",
"event-source": "Isi mmalite",
"event-detail": "Nkọwa"
}
"event-detail": "Nkọwa",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Webhook globali",
"new-outgoing-webhook": "Nuovo webhook in uscita",
"no-name": "(Sconosciuto)",
"Platform": "Piattaforma",
"package": "Pacchetto",
"OS": "SO",
"Meteor": "Meteor",
"Database": "Banca dati",
"Node": "Node",
"Node_version": "Versione Node",
"Meteor_version": "Versione Meteor",
"Database_type": "Tipo di database",
@@ -2339,5 +2345,8 @@
"event-severity": "Gravità",
"event-action": "Azione",
"event-source": "Origine",
"event-detail": "Dettaglio"
}
"event-detail": "Dettaglio",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "グローバルWebフック",
"new-outgoing-webhook": "発信Webフックの作成",
"no-name": "(名前なし)",
"Platform": "プラットフォーム",
"package": "パッケージ",
"OS": "OS",
"Meteor": "Meteor",
"Database": "データベース",
"Node": "Node",
"Node_version": "Node バージョン",
"Meteor_version": "Meteor バージョン",
"Database_type": "データベースの種類",
@@ -2339,5 +2345,8 @@
"event-severity": "重大度",
"event-action": "アクション",
"event-source": "ソース",
"event-detail": "詳細"
}
"event-detail": "詳細",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "グローバルWebフック",
"new-outgoing-webhook": "発信Webフックの作成",
"no-name": "(名前なし)",
"Platform": "プラットフォーム",
"package": "パッケージ",
"OS": "OS",
"Meteor": "Meteor",
"Database": "データベース",
"Node": "Node",
"Node_version": "Node バージョン",
"Meteor_version": "Meteor バージョン",
"Database_type": "データベースの種類",
@@ -2339,5 +2345,8 @@
"event-severity": "重大度",
"event-action": "アクション",
"event-source": "ソース",
"event-detail": "詳細"
}
"event-detail": "詳細",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Глобальные Веб-Хуки",
"new-outgoing-webhook": "Новый исходящий Веб-Хук",
"no-name": "(უცნობი)",
"Platform": "პლატფორმა",
"package": "პაკეტი",
"OS": "ოპერაციული სისტემა",
"Meteor": "Meteor",
"Database": "მონაცემთა ბაზა",
"Node": "Node",
"Node_version": "Node ვერსია",
"Meteor_version": "Версия Meteor",
"Database_type": "მონაცემთა ბაზის ტიპი",
@@ -2339,5 +2345,8 @@
"event-severity": "სიმძიმე",
"event-action": "მოქმედება",
"event-source": "წყარო",
"event-detail": "დეტალი"
}
"event-detail": "დეტალი",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "គេហទំព័រសកល",
"new-outgoing-webhook": "Webhook ចេញថ្មី។",
"no-name": "(មិនស្គាល់)",
"Platform": "Platform",
"package": "Package",
"OS": "OS",
"Meteor": "Meteor",
"Database": "មូលដ្ឋានទិន្នន័យ",
"Node": "Node",
"Node_version": "កំណែថ្នាំង",
"Meteor_version": "កំណែ Meteor",
"Database_type": "ប្រភេទមូលដ្ឋានទិន្នន័យ",
@@ -2339,5 +2345,8 @@
"event-severity": "ភាពធ្ងន់ធ្ងរ",
"event-action": "សកម្មភាព",
"event-source": "ប្រភព",
"event-detail": "ព័ត៌មានលម្អិត"
}
"event-detail": "ព័ត៌មានលម្អិត",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "គេហទំព័រសកល",
"new-outgoing-webhook": "Webhook ចេញថ្មី។",
"no-name": "(មិនស្គាល់)",
"Platform": "Platform",
"package": "Package",
"OS": "OS",
"Meteor": "Meteor",
"Database": "មូលដ្ឋានទិន្នន័យ",
"Node": "Node",
"Node_version": "កំណែថ្នាំង",
"Meteor_version": "កំណែ Meteor",
"Database_type": "ប្រភេទមូលដ្ឋានទិន្នន័យ",
@@ -2339,5 +2345,8 @@
"event-severity": "កម្រិតធ្ងន់ធ្ងរ",
"event-action": "សកម្មភាព",
"event-source": "ប្រភព",
"event-detail": "ព័ត៌មានលម្អិត"
}
"event-detail": "ព័ត៌មានលម្អិត",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "グローバルWebフック",
"new-outgoing-webhook": "発信Webフックの作成",
"no-name": "(名前なし)",
"Platform": "플랫폼",
"package": "패키지",
"OS": "운영체제",
"Meteor": "Meteor",
"Database": "데이터베이스",
"Node": "Node",
"Node_version": "Node.js版本",
"Meteor_version": "Meteor 버전",
"Database_type": "데이터베이스 유형",
@@ -2339,5 +2345,8 @@
"event-severity": "심각도",
"event-action": "작업",
"event-source": "출처",
"event-detail": "세부 정보"
}
"event-detail": "세부 정보",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "グローバルWebフック",
"new-outgoing-webhook": "発信Webフックの作成",
"no-name": "(名前なし)",
"Platform": "플랫폼",
"package": "패키지",
"OS": "운영체제",
"Meteor": "Meteor",
"Database": "데이터베이스",
"Node": "Node",
"Node_version": "Node.js版本",
"Meteor_version": "Meteor 버전",
"Database_type": "데이터베이스 유형",
@@ -2339,5 +2345,8 @@
"event-severity": "심각도",
"event-action": "작업",
"event-source": "출처",
"event-detail": "세부 정보"
}
"event-detail": "세부 정보",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
+11 -2
View File
@@ -949,6 +949,12 @@
"global-webhook": "Globalūs žiniatinklio kabliukai (Webhooks)",
"new-outgoing-webhook": "Naujas siunčiamas žiniatinklio kabliukas",
"no-name": "(Nežinoma)",
"Platform": "Platforma",
"package": "Paketas",
"OS": "OS",
"Meteor": "Meteor",
"Database": "Duomenų bazė",
"Node": "Node",
"Node_version": "Mazgo versija",
"Meteor_version": "Meteor versija",
"Database_type": "Duomenų bazės tipas",
@@ -2339,5 +2345,8 @@
"event-severity": "Rimtumas",
"event-action": "Veiksmas",
"event-source": "Šaltinis",
"event-detail": "Išsami informacija"
}
"event-detail": "Išsami informacija",
"event-ip": "IP address",
"event-attempts": "Attempts",
"integrityReportTitle": "Filesystem integrity"
}
Loaded 100 of 200 files, more files were not shown because too many files have changed in this diff. Show more