Releases: wekan/wena
Releases · wekan/wena
Release list
v0.09
AROS x86 32-bit (ABIv0) and ARM 64-bit builds: wena-aros-i386 and wena-aros-arm64
- AROS runs on more CPUs than x86-64, and Wena is now built for every one
that has a published cross-compiler and SDK:wena-aros-i386: the 32-bit ABIv0 line of deadwood2/AROS that AROS
One and the other i386 distributions run. It was in the catalog as
planned.wena-aros-arm64: AROS's AArch64 port (raspi-aarch64, Raspberry Pi
3/4/5).
- Both build in BlitterStudio's AROS cross-compiler images
(midwan/aros-compiler:i386-arosand:aarch64-aros), pinned by digest,
with the same SDL2 2.32.10 and AROS port aswena-aros-amd64. They are
two more Amiga jobs in the release workflow, and the release check takes
each file only as a relocatable ELF of its own CPU. - AROS on m68k runs
wena-amigaos-m68k. AROS's 32-bit ARM (raspi-armhf)
and PowerPC (sam440, Efika) ports have no published cross-compiler or SDK,
so they are noted inconfig/targets.tsvrather than built. - Those images carry a compiler and an SDK and little else, so what needed
Python or patch in the container now happens on the host first
(scripts/prepare_amiga_sources.py). It extracts SQLite for every Amiga
target, and applies AROS's SDL2 port with Wena's edits (no OpenGL, SDL's
own iconv, wcslen and wcscmp) for every AROS CPU. It stops when the port
no longer has the lines it drops. - Tests:
prepare-amiga-sourceschecks the prepared tree, a missing archive
and a changed port refused, and that the AROS container path needs no
Python, patch or sed.amiga-desktop,target-catalogand
build-entrypointscheck the two images, the catalog, and a refused ELF
of the wrong CPU.
Thanks to xet7.
AmigaOS 3 with RTG draws Wena inside its window, and the mouse points where it is drawn
- wena7 screenshot (FS-UAE, AmigaOS 3, 68040, RTG): Wena ran and showed
All Boards, but the frame was drawn at the Workbench screen's top-left
corner, over everything, and only a stray piece of it was in the "WeKan
Native" window. - The cause is in the pinned AmigaOS 3 SDL fork. The window is a
GimmeZeroZero one on the Workbench screen, and its RastPort's BitMap is
the screen's. The fork wrote that bitmap directly, or scaled into it, at
(0, 0). Every update took the scaling path, because the window's outer
Width, borders included, is always wider than the frame. scripts/patches/sdl2-amigaos3-window.patch, applied for both
wena-amigaos-m68kandwena-amigaos-m68k-aga: a window on the
Workbench screen gets its frame through WritePixelArray into its own
RastPort, where the layers place and clip it, within the inner
GZZWidth/GZZHeight. The direct video memory path stays for a window on
its own screen.- The mouse is from the window's GZZMouseX/GZZMouseY. An IntuiMessage's
MouseX/Y count from the outer corner even in a GimmeZeroZero window, so
clicks were off by the border sizes. - A kept SDL build is reused only when it was made with the current
patches. - Checked for the same fault elsewhere: AROS's SDL port already draws
through the window's RastPort at its border offset, and AmigaOS 4 uses
the system's own SDL2, so neither needs it. - Tests:
amiga-desktopchecks that the window patch applies to the
pinned fork, alone and with the AGA patch. Its windowed path writes only
through the window's RastPort, clipped to the inner area, and never locks,
scales or reads the outer size. The mouse is the inner one, and both
builds apply the patch before CMake.
Thanks to xet7.
WeKan's Admin Panel: People with Edit User, Login, Announcement and Version
- The member menu's Admin Panel (for an admin) opens WeKan's Admin Panel:
its header's tabs (Settings, People, Attachments, Problems) and each tab's
left menu, in WeKan's order. Wena's panes work; the rest are there,
disabled. The house goes back to the board. - People / People: WeKan's table of every user, by username: Edit,
Username, Email, Admin, Active Person and Created at (WeKan's 'LLL'
date). A disabled account is struck through, as WeKan's<s>. The Active
icon (a check or a ban) togglesloginDisabled. Edit User edits
Username, Full Name, Initials, Admin, Email and Active, with WeKan's taken
and invalid errors. The last admin who can log in cannot be demoted or
deactivated (WeKan's "there must be at least one admin"), and an admin
who removes their own rights is taken back to the board. - People / Login: WeKan's "Login: Allow" with Forgot password and
Self-Registration, ticked when allowed and written at once to
settings.disableForgotPasswordanddisableRegistration. Wena never
makes WeKan's settings document: until WeKan has run on the files, the
checkboxes cannot be changed and the pane says so. - Settings / Announcement: WeKan's Active System-Wide Announcement and
its message, saved to WeKan's announcement. It is made as WeKan's
bootstrap makes it when there is none. Its version - WeKan's
announcementVersion, a djb2 over the id, title and body in UTF-16
units - and the user'sprofile.dismissedAnnouncementVersionare read
and written, matching WeKan's own values. - The board shows WeKan's announcement bar under the header (
#f8ecbd,
the message centred, a close cross) while the announcement is on and the
user has not dismissed this text. Closing it writes
profile.dismissedAnnouncementVersion, as WeKan's dismissAnnouncement
does, so a dismissal holds in both, and an edited announcement shows
again. - Settings / Version: what Wena runs on: the database file, SQLite, SDL,
the platform, and the counts of people and boards. --show admin-version,admin-announcement,admin-peopleand
admin-logincapture the panes.- Tests:
admin-panel: the tabs and panes, Wena's four enabled, the house,
People's Active and Edit, Edit User's Save and close, Announcement's
Save, Login's checkbox writing the flag the other way and doing nothing
without WeKan's settings, a disabled pane falling back, and the date.wekan-sync: People by username; the last-admin guard, with a
disabled admin not counting; Announcement made, then changed;
announcementVersionmatching Node's for three texts, one with Finnish
letters, an emoji and a dash; the dismissal round trip; Login refused
without WeKan's settings and keeping its other fields.amiga-aganow checks that every page that presents a frame also
gives it to the AGA screen.
Thanks to xet7.
WeKan's member menu, with Edit Profile and Change Settings that save to the user's WeKan profile
- The menu under the user's name is WeKan's memberMenuPopup now, in its
order and with its icons. It has two columns when one would run past the
window. All Boards, Admin Panel (for an admin only), Edit Profile, Change
Settings and Change Language work. The rest are there as WeKan has them,
disabled until Wena does them. - Edit Profile (editProfilePopup) edits Full Name, Username, Initials and
Email, intoprofile.fullname,username,profile.initialsand the
firstemails[].address, which is made{address, verified: false}when
the user has none. It shows WeKan's errors when another user has the
username or the email (in any case), when the username is empty or has a
space, and when the email has no @. The name in the header changes on save. - Change Settings (changeSettingsPopup) has WeKan's toggles: Show desktop
drag handles, Submit editors with Enter, Open many cards at once and the
checklist sound. Each is written at once to its profile field, and drag
handles apply to the board straight away. "Show cards count if list
contains more than" (profile.showCardsCountAt, -1 and up) and the rescue
dialogue setting are written on Save. - New icons, drawn as WeKan's Font Awesome ones: key, flag, sign-out, font,
picture and paperclip. A text key that only Wena's named texts had now
also falls back to its English there. --show member-menu,--show edit-profileand--show change-settings
capture them.- Tests:
member-settingschecks the menu's order, Admin Panel shown only
to an admin, the enabled entries, the forms' fields in and out, Save,
close and the card count's bounds.wekan-syncchecks the profile round
trip, the email array with FerretDB's types, taken and invalid usernames
and emails changing nothing, and the settings fields, refusing a field
name that is not plain letters.
Thanks to xet7.
WeKan's mobile/desktop toggle and Show desktop drag handles work on the board
- The mobile/desktop toggle in the header works now. In mobile mode, as
WeKan'sbody.mobile-mode, every list takes the board's whole width and
the lists stack one under another, each as high as its cards (a collapsed
one is WeKan's 60 pixel bar), and the page scrolls. The icon is WeKan's
fa-desktop or fa-mobile, and the choice is the user's
profile.mobileMode, asUsers.setMobileModewrites it. - Show desktop drag handles now draws WeKan's arrows icon on every
minicard (20 pixels at its right, 28 down; a 44 pixel strip in mobile
mode), every list header and every swimlane bar, and only those icons drag.
A click elsewhere on a card still opens it, and a click on a list's or
swimlane's title still renames it. Before, the toggle swapped the card
drag for an older labelled handle row. --show mobileand--show drag-handlescapture either state.- Tests:
nuklear-boardrenders with the real Nuklear. In mobile mode the
lists stack at the same left edge and the heights add up. Without
handles the whole card, header and bar drag; with them only the 20, 22
and 26 pixel icons (44 in mobile mode), a card body click opens the card,
...
v0.08
The amigaos4-ppc and haiku-amd64 release builds compile and link again
- v0.07 was published without these two files.
- amigaos4-ppc: the PowerPC GCC stopped on
-Werror=maybe-uninitialized
in the JPEG decoder: it could not see that the component values are set
for each of the image's 1 or 3 components before they are read. They
start at zero now. Every source was rechecked with GCC at -O1, -O2, -O3,
-Os and -Og. - haiku-amd64: the link stopped on
std::__throw_length_error. SDL's
Haiku video is C++ (BWindow,std::vector), and gcc links C only. The
Haiku release now links-lstdc++after SDL's static archive.
libstdc++ ships with Haiku, as its ownlibbedoes. - Tests:
release-link-flagschecks that Haiku links the C++ runtime after
SDL and that no other system does.
Thanks to xet7.
Each release file is attached as soon as its own build passes, and Release all missing adds what a release lacks
release-all.ymlattached nothing until every build had finished, so one
slow or failed job held back all the others' files. Now each build job
attaches its own file the moment it has been built and checked
(scripts/attach_release_files.sh, three tries, replacing a file of the
same name). Windows files are attached after their smoke test on Windows.
The last job no longer uploads binaries: it downloads what the release has,
writesSHA256SUMSover all of it, and names anything still missing.- A cancelled run used to attach nothing. Now each attach step runs even
after a cancel, whenever its own build step succeeded, and the
SHA256SUMSjob runs after a cancel too (always()). So every file that
finished building is on the release, with its checksum. release-all.ymlbuilds only the giventargetswhen asked, and can be
called by another workflow.- The new
release-all-missing.yml("Release all missing") compares the
newest release's files (or a named release's) with the ready targets
(package_desktop_release.py missing-from). It runsrelease-all.ymlfor
just the missing ones, from the current branch, so a build fixed after the
release is built with its fix. It never makes a new version, and starts
nothing when nothing is missing. Menu option 3's "Build missing files for
the newest release" now starts it. - Tests:
release-workflowchecks that every step is limited to the asked-for
targets, that each job's last step attaches its file even after a cancel,
that no job or step is skipped by a cancel, the Windows order,
the checksums job and the missing workflow;attach-release-fileschecks
the script with a fakegh;build-entrypointschecks the menu's
workflow. Both workflows pass actionlint.
Thanks to xet7.
v0.07
AmigaOS 3 opens WeKan's files: SQLite no longer seeks past the end of a file
- wena6 log: both AmigaOS 3 builds (RTG and AGA) stopped on WeKan's
database with no reason given. Running the released
wena-amigaos-m68kunder vamos (amitools' AmigaOS emulator) traced
it. SQLite's first look at the header of the new, empty
wekan.sqliteseeked to offset 24. AmigaDOS cannot Seek() past the
end of a file, and libnix's lseek() makes up for it by writing the
gap from memory it never cleared. The file became 24 stray bytes
("ar(0)) = 0 AND card_id N"), and ATTACH failed with "file is not a
database", on that start and every start after it. - The Amiga builds' SQLite (
-DUSE_PREAD, withpreadandpwrite
fromserver/sqlite_amiga_vfs.c, declared by
server/sqlite_amiga_io.h) now reads and writes at an offset without
seeking past the end. A read there is the end of the file; a write
there pads with zeros first. This covers AmigaOS 3, AmigaOS 4 and
AROS alike. - A
wekan.sqlitealready spoiled this way (not empty, under 512
bytes, without SQLite's header) is renamed to
wekan.sqlite.not-a-database, never removed, and a new database is
made. - So that the next failure says why, a failed open now names its step
and SQLite's reason:- each step of opening WeKan's files is logged on its own;
wena_sqlite_openand the attach record why they failed;- SQLite's own error log (the OS call, errno and file of a failed
open, the SQL of a failed statement) goes to the debug log.
- Tests:
amiga-desktopbuilds SQLite with the Amiga options over an lseek()
that behaves like libnix's. A fresh attached file is a sound
database. The same build without the new options fails "file is
not a database", as on the Amiga.wekan-files: the spoiled file is set aside twice under two names;
a real header, an empty file, a large file and a missing one stay.
Thanks to xet7.
v0.06
Debugging a start that fails, as on AmigaOS 3.2: wena-debug-log.txt beside the program, and the last steps on screen
- On AmigaOS 3.2 Wena said only "Unable to open the local Wena desktop":
outside a checkout withoutWENA_LOG_DIRthere was no log, and every
reason it had was dropped. - Each start now writes
wena-debug-log.txtbeside the executable
(PROGDIR:wena-debug-log.txton AmigaOS and AROS, which needs no program
name - a Workbench start has none), holding the last run.WENA_LOG_DIR
and a checkout's.tools/log/wenastill come first. - The log's lines are also kept in memory, and a start that fails prints
its last 16 where it was started - the Shell or Workbench output window -
then the log file's name. - What is logged: the compiler, the SDL built with and run with; on
AmigaOS 3 and AROS the Exec version, the stack, free memory (largest
block, fast and chip) and, on AmigaOS 3, the CPU and FPU, with a warning
when they are below the 68040 and FPU the build needs; each startup step;
SDL's video driver, display mode and renderer; and when SDL cannot start
video, open the window or make the renderer, SDL's reason and its video
drivers. On AmigaOS 3 it adds that SDL there needs an RTG screen
(Picasso96 or CyberGraphX), since it is built without AGA. - The log's formatter is Wena's own, bounded: C89 has no vsnprintf.
- Tests:
debug-log(the formatter, cut lines, the last 48 lines,
wena-debug-log.txt beside the program on each system and PROGDIR: on the
Amiga, the last run only, WENA_LOG_DIR first, no folder and an unwritable
one),desktop(a start SDL refuses prints its steps, SDL's reason and
drivers, with and without WENA_LOG_DIR; a start that works prints none).
Thanks to xet7.
A separate AmigaOS 3 AGA executable, wena-amigaos-m68k-aga, built by GitHub Actions
wena-amigaos-m68kneeds an RTG card; this one is for AGA without one.
It is built from the same sources withWENA_AMIGA_AGA, in the same
pinned amigadev/crosstools image, as a newamigajob in the release
workflow.- AGA has no 32-bit screen. SDL's AGA path opens an 8-bit screen of the
window's size, so the window is 640x512 (PAL hi-res interlaced) and not
resizable. Wena draws into its own 32-bit frame with SDL's software
renderer and maps each frame onto 256 colors
(client/platform/aga_palette.c): WeKan's UI, label and board colors
first and exact, then a grey ramp for anti-aliased text and a 5x5x5 cube.
A color is matched the first time it is seen and remembered, since
matching all 32768 at the start would take seconds on a 68040. With an
RTG card the frame is copied in full color. - It redraws only after input: after two quiet frames it waits for the
next event, or a second, instead of drawing every 16 ms. - It starts with WeKan's « folded, as on a narrow screen, so the header
fits in 640 pixels. - SDL gets
scripts/patches/sdl2-amigaos3-aga.patch. The fork's Kalms
chunky-to-planar writes plane n at Planes[0] + n x 40960, so it is used
only when the screen's bitmap is laid out exactly that way; any other
layout goes through graphics.library's WriteChunkyPixels instead of
writing over memory that is not the screen's. Without vasm in the image
the build still works, through WriteChunkyPixels alone. --screenshotin this build saves what the AGA screen is given: the
8-bit, palette-mapped frame.- Tests:
aga-palette(WeKan's colors exact, every one of the 32768 colors
near, the conversion with alpha and padded rows, no colors given, too
many given) andamiga-aga(the patch applies once to the pinned fork
and guards the c2p, the desktop's AGA branch, an 8-bit 640x512 screenshot
from a host build, the catalog, the workflow, and a non-HUNK file
refused).
Thanks to xet7.
v0.05
All of WeKan's 35 board views are in the Board View menu, and its 16 report charts are drawn
- The Board View menu lists every view WeKan has, in WeKan's order with
its six separators and each view's name and icon, in three columns so
that it fits. The header names the view that is on. The view is kept as
WeKan keeps it - its exact key inusers.profile.boardView- so WeKan
and Wena open a board in the same view; a key WeKan does not have opens
as Swimlanes, as WeKan's own fallback does. - WeKan's 16 report charts are drawn from wekan.sqlite: Dashboard,
Burndown, Burnup, Cumulative Flow, Control Chart, Cycle Time, Lead Time,
Flow Efficiency, Throughput Histogram with its completion forecast, WIP
Run, Pulse, Aging WIP, Blocker Analysis, Monte Carlo Forecasts, Process
Behavior (XmR) and Work Item Size vs. Cycle Time. Each is WeKan's page:
the title, the method note, the chart (two for Monte Carlo and Process
Behavior), the data table and the details, in WeKan's colors. - The numbers are WeKan's:
models/charts.cports
chartCalculations.js,flowAnalytics.js,chartExportRows.jsand
flowAnalyticsRows.js- completion at endAt else archivedAt, UTC days,
Mongo's sort order and JavaScript's stable sort, the Monte Carlo
bootstrap with WeKan's seed - reading cards, lists, activities and the
card change history, removed cards' snapshots included, as
boardChartData.jsdoes (server/wekan_views.c). - The views' and charts' texts are WeKan's translations, looked up by key;
the two forecast texts with__name__placeholders are filled in. - The other views are listed and not yet drawn; they follow.
--show view:KEYwith--screenshotrenders a view.- Tests:
charts(new) computes all 16 charts on three seeded boards both
with WeKan's own JavaScript in Node and with Wena, and requires every
table cell, detail row, note and bar to be the same;wekan-views(new)
loads cards with every field, a removed card's snapshot, lists, users,
activities and the history rows the charts replay, and not another
board's;board-views(new) checks the 35 views, their order,
separators and charts and draws a chart and an empty one;wekan-sync
keeps any view key and refuses a malformed one;desktopopens three
chart views on a WeKan file.
Thanks to xet7.
WeKan's other board views are drawn: Table, Calendars, Time, Timeline, Stats, Gantts, Scrum, Roadmap, Bigboard
- Table: WeKan's columns - Edit, Card, List, Swimlane, Assignees, Members,
Labels as chips, Received, Start, Due, End - with its search, sorting by
any column both ways, 25 cards a page and grouping by swimlane; Edit or
a title opens the card. - Calendar and the Calendar of every board: WeKan's month, week, day and
list, Monday first, opening on the month at today, with Today, Previous
and Next; a card spanning its start to its end and an hour at its
received, due and end dates, the other boards' cards named with their
board. A card clicked opens, on its own board. - Time (time spent, cards with time, overtime, the remaining time until
due, hours by assignee and by card, the adjustments by author), Stats
(the board's status) and Group by Assignee. - Timeline: the points in time of the board's activities, at most 50, and
the lists with every card as it was then - title, description, labels,
members, due date, archived - undoing what happened since. - Gantt (a table a week, a day a column, the received, start, due and end
dates in WeKan's colors), Frappe Gantt and DHTMLX Gantt (bars from start
to due, red when overdue, filled when done, by day, week or month, and
DHTMLX's Task / Start / Duration grid) and Roadmap (the cards grouped by
a text or dropdown custom field, each group's bars). - Product Backlog, Sprints (the sprints, a sprint's goal, state, cards and
events, the releases), Sprint Report and Velocity, from WeKan's sprints,
releases and events and their stored reports. - Bigboard: every board of the user stacked, each with its lists and cards.
- What they read is WeKan's own: custom fields with dropdown items, card
numbers, card.scrum, the board's Scrum settings and members, sprints,
releases and events, and every board's lists (server/wekan_views.c). - The Map view is still listed and not drawn: it needs the uploaded image
decoded, which follows. - Tests:
view-rows(new) computes the Table's order for every sortable
column both ways, grouped or not and with searches, the Calendar's
events, the Time sums, the assignee groups, the Timeline's markers and
its cards at three points in time, the Gantt tasks and the Scrum order
and estimates on three seeded boards both with WeKan's own JavaScript in
Node and with Wena, and requires them to be the same;board-views
draws every one of these views and opens a card from the Table;
desktopopens seven more views on a WeKan file.
Thanks to xet7.
WeKan's Map view is drawn, with Wena's own decoder for the map image
- The Map view shows the board's uploaded map image with a marker for each
card on it - its first label's color, its card number - and, beside it,
WeKan's "Not on the map" list: choose a card, then click where it
belongs. A marker opens its card. Remove the map image takes it off the
board. Both write WeKan's own fields: the card'smapXandmapY
(clamped to 0..100 and rounded, as Card.setMapPosition) and the board's
mapImageAttachmentId. - The image is the attachment's recorded file, or the same name in this
wekan-files/attachments when the bundle has moved. - Wena decodes it itself (
models/image_decode.c, no new library): PNG in
every color type and bit depth with transparency and Adam7, baseline and
extended JPEG, and GIF's first frame with transparency and interlacing.
WebP and progressive JPEG are refused, and the view then says which file
could not be read. - With this, every one of WeKan's 35 board views is drawn.
- Tests:
image-decode(new) decodes 33 PNG, GIF and JPEG images with
known pixels - exactly, JPEG within its loss - and refuses WebP, a
progressive JPEG, a truncated PNG and unknown bytes;wekan-syncwrites
and clears a card's place and removes the image;wekan-viewsreads the
image's file and the cards' places and numbers;board-viewsdraws the
Map without an image, with one - choosing a card to place, Remove - and
with one that could not be read;desktopopens the Map.
Thanks to xet7.
The release builds compile again with GCC's format and truncation checks
- wena5 log: every Linux build stopped in
generate_wekan_defaults.py,
which looked two folders up for a WeKan checkout that a CI checkout of
Wena alone does not have (IndexError). It, and the new logo generator,
takeWEKAN_ROOTor fall back to Wena's own folder, and their--check
passes when there is nothing to compare with. - The BSD, Haiku, Windows cross, AmigaOS and AROS builds stopped on
-Werror=format-overflow: GCC could not prove the SQL built with
sprintffits. The statements are built in 4096-byte buffers (the
notifications one in 4400, room for its two 2048-byte parts), a chart's
day key spells out its ranges, and the notification text and the
control names are copied with their lengths known. - AmigaOS m68k stopped on a label chip's
ythat GCC saw as maybe unset;
it starts from the row. strncpyinto the view rows' fixed fields became a terminating copy,
which GCC's-O3truncation check accepts.- Checked with MinGW-w64 GCC 16 at -O2, -O3 and -Os over every source with
the release flags: no warnings.
Thanks to xet7.
WeKan's header extras: its logo, the « that folds the icons, and Show desktop drag handles
- WeKan's
public/logo-header.pngis drawn after the board title, from
client/platform/logo_data.h, generated by
scripts/generate_wekan_logo.py(whose--checkruns with every desktop
build) and decoded with Wena's own PNG decoder. - The « beside the house folds the header's icons as WeKan's does: the
desktop icon, the drag handles toggle, the star group and the + go, and
» brings them back. - "Show desktop drag handles" is the user's
profile.showDesktopDragHandles, read when the board opens and written
as a Boolean when toggled; with it on, a card moves by its handle only,
and the check or the ban beside it says which. - Tests:
board-feature(the «, the toggle in both states, the desktop
icon doing nothing, the folded header),wekan-sync(the field off until
set, written as FerretDB's bool, nobody and no user),image-decode(the
embedded logo decodes at 97 x 28 with transparency).
Thanks to xet7.
v0.04
WeKan itself opens what Wena wrote: checked with WeKan's bundle on the same wekan-files
tools/wekan-ui/dropin.shchecks Wena as a drop-in with WeKan itself: a
WeKan user is made through FerretDB on an emptywekan-files/db; Wena
opens those files as that user, makes its board and adds a list, a card,
a description and a checklist; then WeKan's own bundle serves the same
files through FerretDB, and its page (Playwright,dropin.e2e.js) shows
the board on All Boards, the list and card on it, and the card's details
with the description and the ticked checklist item. It passes.- What it found: a board WeKan makes carries its schema's defaults
(allowsDescriptionText,allowsChecklistsand 99 more Booleans), and
WeKan hides a part of the board whose field is missing. A board Wena makes
now carries them all, generated from WeKan'smodels/boards.jsinto
server/wekan_defaults_data.hbyscripts/generate_wekan_defaults.py,
whose--checkruns with every desktop build (and passes without a WeKan
checkout, when there is nothing to compare with).
Thanks to xet7.
The language and collapsed lists and swimlanes are the user's, where WeKan keeps them
- With WeKan's files, the language comes from the user's
profile.languageand the language picker writes it there, through a
store the picker can now be given instead of its settings file. A
language WeKan names that Wena does not have resolves to one it has. - Collapsed lists and swimlanes and swimlane heights are the user's
profile.collapsedLists,profile.collapsedSwimlanesand
profile.swimlaneHeights({board: {id: value}}): read when a board
opens and written when they change, the other boards' entries kept. - So nothing of Wena's goes into WeKan's
dbfolder: it holds
wekan.sqlite(and SQLite's -wal and -shm) only, whichdesktopchecks. - Tests:
language-picker(the store, a refused store changing nothing, an
unknown language),wekan-sync(profile.language, the per-board maps,
another board's map kept, only WeKan's fields).
Thanks to xet7.
Wena opens on WeKan's All Boards page, and goes from board to board in one window
- With WeKan's files, the first page is All Boards as WeKan draws it
(client/components/boards/all_boards.c, measured from WeKan's own page,
tests/fixtures/wekan-ui/00-all-boards.json): the header with the house
and the user, the left menu of sections - Remaining, Starred, Home,
Templates, Archive - with their counts, and the boards as tiles in their
board color, "Add Board" first, each with its star. - The boards are the user's from WeKan's documents: their own and template
containers, archived ones in Archive, starred ones from the user's
profile.starredBoards- which the star writes, one level into the
user's profile with FerretDB's types. "Add Board" makes a board as WeKan
does, with its "Default" swimlane and the user its admin. - A tile opens its board; the house before the board's title goes back.
Opening another board releases the board's state and starts its session
again in the same window, with the same database. --show all-boardsand--show open:BOARD(a tile chosen) with
--screenshotor--smoke.- Tests:
all-boards(sections, counts, open, star, Add Board, the archived
and Home negatives, colors),wekan-sync(the board list, stars, a new
board) anddesktop(the files layout, FerretDB's metadata, the first
run's admin and board, reopening, a board switch, All Boards drawn).
Thanks to xet7.
Wena keeps WeKan's own files: wekan-files/db/wekan.sqlite as FerretDB writes it, a drop-in for WeKan's bundles
- Opened without a workspace (double-clicked, or 2) Run), Wena uses WeKan's
files directory:WRITABLE_PATHwhen set - withfilesadded unless it
already ends infilesorwekan-files, as WeKan'sstart-wekan.shand
.batdo - elsewekan-filesbeside the program, as WeKan's Windows
executable has it. It makesattachments,avatarsanddb, and keeps
the board indb/wekan.sqlite: the file WeKan's FerretDB bundles
(AppImage, Snap, Docker, Windows) open as databasewekan. - That file is FerretDB's SQLite format, written directly with SQL
(server/ferretdb_sqlite.c): the_ferretdb_collectionstable, one
<collection>_<FNV-1a>table per collection with its_id_index, byte
for byte as FerretDB makes them, and documents with their$stype
schema. Wena reads it with double-quoted strings off, as release builds
of SQLite are. - WeKan's documents are read into Wena's tables in memory
(server/wekan_sync.c): users, boards with their members, labels and
settings, swimlanes and lists with archive state, color and WIP limit,
cards with description, labels, members, assignees and archive state,
checklists and their items. After each frame that changed something,
only the changed fields go back to WeKan's documents, each with its type,
so the fields of a document Wena does not show stay as they were; new
documents get the fields WeKan requires, and a title Wena had to shorten
is not written back unless it was edited. - The user is
WENA_USER(an_idor username), else the first admin; a
new file gets a user "admin" and a board "My board" with WeKan's
"Default" swimlane.WENA_DATABASEand--databasestill open a Wena
workspace file. - Tests:
wekan-files,ferretdb-sqlite(DDL text,$son insert, update,
unset, delete),wekan-sync(import, changed fields only, WeKan's fields
kept, new documents, deletes, rollback, the user) andferretdb-roundtrip,
which runs the FerretDB binary WeKan bundles: FerretDB serves through the
MongoDB driver what Wena wrote, and Wena reads, changes and adds to what
FerretDB wrote. Not yet run against a WeKan server itself.
Thanks to xet7.
The release builds again: v0.03 stopped on every platform on a stale compiled-in license file
- wena4 log: every job of the v0.03 release stopped before compiling with
client/platform/notices_data.h is stale. The licenses compiled into the
executable includeconfig/release-dependencies.json, which the AROS
rename (aros-x86 to aros-amd64) changed without regenerating them. The
current header matches its sources again. - New suite
generated-sourcesruns the checks every desktop build runs
first (scripts/check_desktop_sources.sh: pinned dependencies, SVGs,
migrations, translations, font and licenses), so a stale generated file
fails the test run instead of the release. Its negative case changes the
dependencies on a copy and requires the check to report the stale header.
Thanks to xet7.
Card details, Card Actions, the Add Card composer and the sidebar look and work like WeKan's
- Card details are WeKan's panel instead of a column of buttons: a header
with the caret that collapses it, the title (click it to edit, as in
WeKan), Card Actions, Maximize and Close Card, then the Labels,
Description and Checklists sections, each with WeKan's caret, icon and
16px gray heading and each foldable. They show the card's label chips, its
description and its checklists, whose items can be ticked there. - Card Actions (the hamburger on a minicard and in the details) is WeKan's
popup with the items Wena carries out, in WeKan's order and groups: Move to
Top, Move to Bottom, Move Card and Move Card to Archive. Move to Top and
Bottom are new: one version-checked reorder within the card's list. As in
WeKan, the minicard's hamburger no longer opens the details. - Add Card is WeKan's inline composer in the list: a white card with the
text box, the blue Add and the close cross, above the cards for Add Card
to Top of List and in place of "+ Add Card" for the bottom. Enter adds and
the composer stays for the next card; a card added to the top is moved
there, and a move that fails is reported. - The sidebar is WeKan's home view, 420px under the header: the close
cross, Board Settings, then foldable Members (the board's members and its
own user), Labels (WeKan's colored chips) and Activities, and the Archive. - Label chips on minicards and in the details are WeKan's: bold text on the
label's color, 4px rounded, side by side. Checklists show their title in
bold with a finished/total count, and items as WeKan's checkboxes. --show card:ID,card-menu:ID,list-menu:ID,add-card:LISTor
sidebarwith--screenshotrenders each state WeKan's capture has, for
comparison.- Fixed on the way: Nuklear's
nk_spacingon a one-column row starts a
new row, which left an empty row after each read-only checklist item;
raw colors in the look module were drawn black. - Tests:
card-actions(suite) drives the popup's items against SQLite,
with disabled items and unknown cards as negatives; move to top and bottom
are incard-move-reorder-sqlite; the composer, details header and
sections, sidebar folds and chips are incard-create,board-feature,
card-description,nuklear-checklist-contentsandnuklear-board.
Thanks to xet7.
A board from WeKan's file looks as WeKan draws it: list widths, checklists on minicards and the user's name
- Lists are as wide as WeKan keeps them: each list's
width(WeKan's
DEFAULT_LIST_WIDTHis 220) is read in, and the minicards in it are 34
narrower, as in WeKan. A list without a width of its own is 220 wide in
WeKan mode, 272 otherwise; a width outside WeKan's 100..1000 is not used. - Checklists on minicards follow WeKan's board field
allowsChecklistsOnMinicard(on unless the board turns it off), read in
and written back under that name; Wena wrote a field WeKan does not have.
A board made in Wena gets WeKa...
v0.03
The NetBSD, DragonFly BSD, Haiku and OpenBSD builds compile again; FreeBSD riscv64 waits for packages
- wena3 log: NetBSD amd64 and arm64, DragonFly BSD and Haiku stopped on
server/executable_path.c: their GCC rejects anifwith more statements
after it on a line of its own (-Werror=misleading-indentation), which
clang - and so the header check of v0.02 - accepts. Those lines now hold one
statement each.tests/test_bsd_sources.pyalso compiles every desktop
source with GCC 13 on NetBSD's headers (the host's GCC, or the pinned
gcc:13image), reproduced the error at the same line before the fix, and
rejects a probe of the pattern. - OpenBSD amd64 and arm64 stopped unpacking SDL2: OpenBSD's
tarhas no
--strip-components.scripts/extract_archive.pyunpacks the pinned
archives without their top directory on every system, keeping modes and
links and refusing entries or links that leave the destination
(tests/test_extract_archive.py, suiteextract-archive). - FreeBSD riscv64 is planned again: FreeBSD publishes no riscv64 packages for
14 or 15, so its virtual machine has no Python, make or X11 to build with.
Cross-compiling it from Linux is the way there. - Verified here: GCC 13 on NetBSD 10.1's headers reproduced the release
run's error atexecutable_path.c:31and passes after the fix; all desktop
sources compile with clang for FreeBSD, OpenBSD and NetBSD and with GCC for
NetBSD; the pinned SDL2 and llvm-mingw archives unpack and run. The BSD and
Haiku builds themselves are verified by the next release run.
Thanks to xet7.
The AROS x86-64 release file is wena-aros-amd64, named for its CPU as every other file is
wena-aros-x86was an x86-64 file (ELF 64-bit LSB relocatable, x86-64),
while "x86" names 32-bit x86 everywhere else. The target is now
aros-amd64, its filewena-aros-amd64, aswena-linux-amd64and
wena-windows-amd64.exeare.- The release check takes the CPU from the name: an
aros-amd64file must
be a 64-bit x86-64 relocatable ELF and anaros-i386one a 32-bit i386
one, and an AROS name with any other CPU is refused. The target catalog
allows no target ending in the ambiguous-x86. config/targets.tsvlists AROS per CPU:aros-i386for the 32-bit ABIv0
line of deadwood2/AROS (planned until its build is in the release
workflow), AROS on m68k runningwena-amigaos-m68k, and AROS on ARM having
no published toolchain or SDK to build with.
Thanks to xet7.
The desktop opens again after it was closed normally
- Run, and a double-click on the desktop, said "Unable to open the local Wena
desktop" for a board that was there. The startup check that an actor or
board named by mistake writes nothing opened the file read-only, and a
read-only handle cannot read a WAL database whose-walfile a clean exit
removed ("unable to open database file"). So every launch after a normal
quit failed, and only a launch after a crash worked. - The check now opens the existing file read-write without creating it, with
PRAGMA query_only=ON: a missing file still fails, and nothing can be
written. The debug log names which check failed and SQLite's reason. tests/test_desktop.shcloses a WAL workspace cleanly (no-walor-shm
file) and opens it, and checks that an unknown actor there still changes
nothing. With the read-only handle back, it fails as Run did.
Thanks to xet7.
The desktop board looks and works like WeKan's: its colors, fonts, header, lists, cards and menus
- Measured from WeKan, not chosen by eye:
tools/wekan-ui/capture.e2e.js
runs in WeKan's Playwright suite against a running WeKan and records each
state of a seeded board (the board, list and swimlane menus, Add Card, the
sidebar, card details and its menu) with every visible control's text,
tooltip, icon, place and colors.tools/wekan-ui/pin.pypins them in
tests/fixtures/wekan-ui. client/components/common/wekan_look.cholds WeKan's colors (the
#2980b9header,#dededecanvas,#e4e4e4list headers, white
minicards with#4d4d4dtext, white popups with gray title bars,#f7f7f7
panels, the red#ce1414of a list over its WIP limit), its fonts (Roboto
and Roboto Bold, now embedded with its provenance, at WeKan's 12 to 19 px)
and its Font Awesome icons as vectors. The Nuklear theme uses the same
palette.- The same controls in the same places, named as WeKan names them: the header
with the board title, Filter, the user and the sidebar toggle; swimlane
headers with their caret and Swimlane Actions; list headers with Collapse,
Add Card to Top of List, Add List and List Actions, and a long title that
wraps; minicards with their caret and Card Actions; "+ Add Card" under each
list; collapsed lists as a narrow strip with the title stacked; WeKan's
popup menus for lists, swimlanes and the user, the Filter panel and Change
Language. - Dragging works as in WeKan: the whole minicard, list header or swimlane bar
is the handle, and a press and release without moving is a click that opens
the card or edits the title. The swimlane resize handle is WeKan's 10 px
bar, shown when hovered. - Every control is recorded with its WeKan name and place each frame, which
is what tests click.--screenshot FILEsaves the last frame as a BMP, to
set beside WeKan's captured screenshots.
An icon's tooltip is drawn at window level: opened from inside a header
row, it broke the frame, so nothing after the hovered icon was drawn. tests/test_wekan_ui_parity.py(suitewekan-ui-parity) checks every
Wena color against WeKan's capture, and the WIP color against WeKan's
stylesheet when the WeKan checkout is next to Wena. The board, list, card,
filter, theme, SVG, collapse and swimlane-resize suites now click WeKan's
control names and check WeKan's colors, including the hovered tooltip, the
sidebar opening below the header, and a missing selection marking nothing.
Thanks to xet7.
v0.02
The desktop for AmigaOS 3.x, AmigaOS 4 and AROS: wena-amigaos-m68k, wena-amigaos4-ppc, wena-aros-x86
scripts/build_desktop_amiga.sh TARGET OUTPUTcompiles the desktop in the
pinnedamigadev/crosstoolsimage of each into one static executable: the
image's SDL2 2.30 on AmigaOS 4 (PowerPC ELF); SDL2 2.32.10 with AROS's own
port (SDL2-2.32.10-aros.difffrom aros-development-team/contrib, without
OpenGL) on AROS x86-64 (relocatable ELF); and on AmigaOS 3.x the SDL2 fork
DevilutionX ships for 68040 with FPU and an RTG card (HUNK). Images and
sources are pinned by digest and SHA-256.- SQLite runs there without WAL, mmap or file locks, through an
amigaVFS
that keeps AmigaDOS names such asPROGDIR:xas they are. Wena's
journal_mode=WALthen simply staysdelete; other platforms keep WAL. - The platform code knows
Volume:paths, keeps the board in
PROGDIR:wena.sqlite(ENV:is a RAM disk), publishes a new workspace with
dos.libraryRename()(which never replaces), retries settings writes
because AmigaDOSRename()does not replace, keeps the collapse preferences
file within the original FFS's 30 characters, askslocale.libraryfor the
language and runs on a 1 MB stack (AmigaOS 4$STACKcookie, libnix
__stack, AROSNewStackSwap). - Verified here: all three build, link statically and pass the format checks
(scripts/check_release_executable.pynow knows HUNK, static PowerPC ELF
and AROS's relocatable ELF); the desktop with the exact Amiga SQLite options
and VFS creates and reopens a board on Linux. Not run on an Amiga or an
emulator yet. Tests:amiga-desktop,debug-log,build-entrypoints.
Thanks to xet7.
The desktop for Android and iOS: wena-android-arm64.apk and wena-ios-arm64.ipa
scripts/build_desktop_android.sh OUTPUT_APKbuildslibmain.so- the
desktop with SDL2 2.32.10 and SQLite linked in - with SDL's own Java glue and
a smallfi.wekan.wena.WenaActivity, directly with the NDK, javac, d8,
aapt2, zipalign and apksigner (no Gradle). Min SDK 21, target SDK 37,
16 KB-page aligned. It is signed with the release key from the repository
secrets, or a debug key with a warning.scripts/build_desktop_ios.sh OUTPUT_IPAbuilds SDL2 for iOS with CMake and
linksPayload/Wena.app(iOS 15 or newer), unsigned: re-sign it with your
own certificate, AltStore or Sideloadly. Apps built with the iOS 27 SDK must
use scenes, which SDL 2 does not, soclient/platform/ios/scene.mputs
SDL's windows into the app's scene.- On a phone the board lives in the app's own data folder
(SDL_GetPrefPath), the language comes from the system, the board is laid
out in density-independent units and drawn at native pixels, touches land
where they are drawn, the keyboard shows only while a field is edited, and a
failure is shown in a message box. On Android a new workspace is published
withrename()after checking nothing is there, because SELinux refuses
link()in the app's folder. - Verified here: the APK passed the smoke test in the Android 17 (API 37)
emulator, on a second run and after an update over itself, and a card was
added by touch; the Simulator app passed on iOS 27.0 and 26.5. Real phones,
Android 5-16 and Xcode 16 builds are verified by use and the release run.
scripts/check_release_executable.pychecks the APK's only library is
arm64libmain.soloading Android's own libraries, and the IPA'sWena
loads only iOS's frameworks. Tests:mobile-desktop,debug-log,
build-entrypoints.
Thanks to xet7.
Every release file is the desktop GUI, one self-contained wena-TARGET per platform, from one workflow
release-all.ymlis the only release workflow.release-desktop.yml, the
.github/release/*.shscripts andclient/main.care gone: the program they
released printed one line in a terminal. Every target inconfig/targets.tsv
is now the native Nuklear desktop, named after its platform -
wena-linux-amd64,wena-windows-amd64.exe,wena-freebsd-amd64- and
attached beside oneSHA256SUMS, without a.sha256per file or a separate
notices archive.- 28 platforms: Linux amd64, arm64, armhf, armel, i686, riscv64, ppc64le,
s390x and mips64le; FreeBSD amd64, arm64 and riscv64; NetBSD and OpenBSD
amd64 and arm64; DragonFly BSD and Haiku amd64, built natively in virtual
machines (cross-platform-actions v1.6.0,scripts/build_desktop_release_vm.sh);
macOS arm64 and amd64; Windows amd64, i686 and arm64; and, below, AmigaOS
3.x, AmigaOS 4, AROS, Android and iOS. - SDL2 and SQLite are linked into each one from the pinned sources, as before;
the licenses of everything in it are now compiled in too
(scripts/generate_notices.py), andwena --licensesprints them. - wena2 log: linux-armel and linux-mips64le stopped at once, because the
debian:bookwormimage no longer lists those CPUs. They build in Debian's
per-architecture images,arm32v5/debian:bookwormand
mips64le/debian:bookworm, with the same glibc 2.36. Under QEMU, loading
Mesa's DRI driver crashes on MIPS64 (SIGBUS) before Wena draws anything,
whichever Gallium driver is chosen, so that one X11 smoke test keeps Mesa's
driver unloaded and uses SDL's software renderer. Every X11 smoke test now
checks the application's own exit status rather thanxvfb-run's. - Two compile errors that would have stopped the BSD builds, found by
compiling every desktop source against FreeBSD 15.1, OpenBSD 7.9 and NetBSD
10.1 headers (tests/test_bsd_sources.py, suitebsd-sources): an unused
static helper inserver/executable_path.con FreeBSD, NetBSD and DragonFly
(-Werror), and NetBSD's<sys/sysctl.h>needing_NETBSD_SOURCE. ./build.sh build TARGETbuilds the same release file intorelease/the
way the workflow does: Linux targets in the workflow's own container image
(scripts/toolchain.pyand the workflow are checked to agree), Windows with
MinGW-w64 (arm64 with the pinned llvm-mingw, now also on macOS), macOS with
Xcode. A BSD or Haiku target builds on that system itself.- Verified here: macOS arm64 and amd64 built, ran headless twice and printed
their licenses; Windows amd64, i686 and arm64 built and were checked
self-contained; linux-arm64 and linux-armel built and passed the headless
and X11 smoke tests in their containers, and linux-mips64le too, under QEMU. The BSD and Haiku virtual-machine builds, the Windows runs and
the other Linux CPUs are verified by the next release run. Tests:
release-workflow,target-catalog,toolchain,build-entrypoints,
source-structure,bsd-sources, with negatives (the wena2 image, a target
left out of the workflow, the two BSD errors, a stray release file).
Thanks to xet7.
The desktop compiles its migrations in and reads nothing from its own file
- It assembled the migration bundle from a footer appended to its executable,
found through the executable's path, and opened an appended translation
catalog only to check that it was there. An app bundle, an APK, a signed
iOS app and Amiga'sPROGDIR:either cannot carry appended bytes or cannot
find the file reliably, and OpenBSD has no/procto find it with. The
bundle now comes from the compiled registry, checked against its own
SHA-256 (wena_sqlite_compiled_bundle); nothing is appended. tests/test_compiled_bundle.sh(suitecompiled-bundle) checks the bundle
againstconfig/migrations-lock.json, NULL arguments, and that neither the
desktop nor its build reads or appends a footer. The runtime and
embedded-migration suites test the server's footer reader with a fixture
instead of the removed terminal program.
Thanks to xet7.
build.sh and build.bat install what a build needs on macOS, Windows, Ubuntu, Debian and Fedora
scripts/toolchain.pyruns before every build and installs what is
missing with the computer's own package manager: Homebrew on macOS, apt on
Debian and Ubuntu, dnf on Fedora, Chocolatey or else winget on Windows.
build.shandbuild.batinstall Python 3 first when it is missing.- Per target: gcc, Debian's cross-compilers with their C library, MinGW-w64,
Docker (started when it is not running, with QEMU on arm64 Linux) for
AmigaOS and AROS, and the Android NDK r29. The NDK is downloaded from Google
and checked against the size and SHA-1 in Google's own repository manifest
before it is unpacked into.tools. iOS uses an installed Xcode through
DEVELOPER_DIRwithout changing which one is selected. - Where this computer has no compiler for a Linux target (Fedora, macOS,
Windows), it is built in an Ubuntu 24.04 container with Ubuntu's compiler.
The container's name is a hash of its package list, so a changed list
builds a new one. - On Windows, Git for Windows provides
shandfile, a native MinGW-w64 gcc
builds the Windows target, MSYS2 provides SDL2, SQLite and gcc for the
desktop, and apython3shim lets the release scripts call Python.
android-arm64.shuses the NDK's prebuilt compiler for this computer
instead of always Linux's. build allbuilds every target this computer can build and lists the
others with the reason, such as iOS without Xcode.install TARGET|all|desktop
installs without building.WENA_NO_INSTALL=1only checks.windows-amd64.shaccepts both ways file words a PE executable: file 5.46
(Fedora 42) puts "Windows" before "x86-64".- Verified on this Mac: all ten release targets and the desktop built after
installing what was missing. On fresh Ubuntu 24.04, Debian 12 and Fedora 42
containers, starting without Python, these all built: the host target,
Windows amd64 and the desktop, plus armhf cross-built on Ubuntu and
Debian. Windows was not run he...
v0.01
Security: no test runs SQL read from outside the program (18 GitHub CodeQL cpp/sql-injection alerts)
- GitHub CodeQL code scanning reported alerts #2-#19, "Uncontrolled data in
SQL query": tests read a schema file named on their command line and passed
its text tosqlite3_exec. The same shape was in 62 tests. Their schema,
fixture and migration SQL is now compiled in by
scripts/embed_test_files.pyand read throughtests/support/test_files.h;
a path argument only selects one of those files. Reads that only compare or
hash database and backup files stay, each listed with its reason. - The application was already clear: every value is bound with
sqlite3_bind_*, migrations are embedded and checked against their pinned
SHA-256, and the five places that format SQL text use fixed table and column
names or SQLite's%widentifier quoting. tests/test_sql_sources.py(suitesql-sources) fails when a test that runs
SQL reads a file at run time, when a script passes a.sqlfile without
embedding it, or when the application builds SQL text anywhere new; the
generator and lookup are tested, including an unknown name aborting the
test. All converted suites pass on Linux; on macOS the same 11 suites fail
as before, for Apple's SQLite.
Thanks to GitHub CodeQL.
One self-contained desktop executable per platform, numbered from Upcoming and released from the menu
- Menu option 3) Release (
build.sh release next) numbers the Upcoming section
after the newest release, the way WeKan does (v0.01 ... v9.99, v10.00),
commitsPrepare vX release, pushes, and startsrelease-desktop.yml.
build.sh release missingbuilds and attaches to the newest release. It
refuses uncommitted changes. Tests, Server and Tools move to 4, 5 and 6. release-desktop.ymlpublishes the release with that CHANGELOG section as
its notes, startsrelease-all.yml, and builds 14 executables: Linux amd64
and arm64 natively, armhf, armel, i686, riscv64, ppc64le, s390x and
mips64le under QEMU; macOS arm64 and amd64; Windows amd64, i686 and arm64
cross-compiled and smoke-tested on Windows runners. Each is attached with its
.sha256, beside one notices archive of licenses and provenance.- SDL2 2.32.10 and SQLite 3.53.4 are built from checksum-pinned sources and
linked in (scripts/build_desktop_release.sh), SDL with only video,
rendering and events. A Linux executable needs only glibc and X11 or
Wayland, macOS only its own frameworks, Windows only its system DLLs;
scripts/check_release_executable.pyreads each executable's own library
list and refuses anything else. - The desktop runs on Windows: drive and UNC paths, wide-character file APIs,
a workspace published with no-replaceMoveFileExW, the board in
%APPDATA%\Wena, and the debug log. - gcc 13 rejected 27 one-line
if (...) a; b;statements under
-Werror=misleading-indentation; each is one statement per line now. - Verified here: macOS arm64 and amd64 builds, Linux arm64 and amd64 built on
Ubuntu 22.04 and smoke-tested under Xvfb (glibc 2.34), Windows amd64, i686
and arm64 cross-built and checked. Tests: release flow with gh and git
replaced, numbering and notes, the executable checker against ELF, PE and
Mach-O with negatives, pinned downloads, packaging, and the workflow's
platform list.
Thanks to xet7.
Drag the bar below a swimlane to change its height
- Each expanded swimlane has a bar below it. Dragging it up or down resizes
the lane live, with the up-down resize cursor; release keeps the height,
Escape cancels. Heights are clamped to 160-2000 pixels, the default 360
needs no entry, and the lists inside grow with the lane. - Heights are saved per actor and board with collapsed lanes and lists. The
preferences file is version 2 exactly when it holds heights, so version 1
files keep loading; heights of lanes the board no longer has are dropped. - Tests: a real Nuklear drag test (press, drag, release, Escape, both clamps,
back to the default, a collapsed lane and a layout without the bar), and
preference round trips with strict negatives for every malformed height
line, a full file, and pruning.
Thanks to xet7.
Fix the desktop crash when the mouse reaches a list or swimlane drag handle
- 42 sources included
<nuklear.h>without theNK_INCLUDE_*options that
sdl_nuklear.hset before compiling Nuklear itself. Those options add fields
tostruct nk_context, so the drag handles readcontext->currentat another
offset than Nuklear wrote it (0x4920 instead of 0x4a10), got NULL and crashed
with SIGSEGV, as three macOS crash reports and the debug log showed. - The options now live only in
client/platform/nuklear_options.h, included
before<nuklear.h>in every source and test, and the tests that compiled
Nuklear with two or three of them now use the same set. The narrow clang
C23-extension silence for Nuklear's alignof moved there too, so 24 Nuklear
suites build and pass on macOS again. tests/test_nuklear_options.py(suitenuklear-options) fails when any of
the 100 units includes Nuklear without the options first or sets an option
elsewhere, with negative cases for both.- With no workspace named, also when only
--smokeor--languageis given,
the desktop opens the default board; the desktop suite tests its creation,
reopening and a refused relativeWENA_DATABASE.
Thanks to xet7.
Debug log for every desktop run, and the desktop opens its board when double-clicked
- Each run writes
.tools/log/wena/YYYY-MM-DD_HH-MM-SS/desktop.log: the
arguments, the board opened, the source line of any startup failure with
SDL's error, the window closing, the exit status, and a fatal signal, written
with async-signal-safe calls before the default action, so a crash is visible.
build.sh runaddsrun.logwith everything the app printed and whether it
exited or was killed by a signal.WENA_LOG_DIRchooses another folder. - Started without arguments, as a double-click does,
wena-desktopopened
nothing and printed that it needs a database, actor and board. It now opens
the same local board as Run, created on the first run. - Tests cover the log folder and default board rules with their negative
cases, a written line and a recorded crash in a child process, and run.log's
output, exit code and signal.
Thanks to xet7.
Run opens the native Nuklear desktop, and the desktop builds on macOS again
- Menu option 2) Run and
build.sh runopendist/desktop/wena-desktopon a
local board, created on the first run in the user's data folder or in
WENA_DATABASE, instead of the bootstrap binary that only prints its name.
Given arguments go to the desktop unchanged. - The desktop did not compile with Apple clang 21:
SDL2/SDL.hwas not found
throughsdl2-config,mkdtempwas hidden by_POSIX_C_SOURCE, and the pinned
Nuklear's alignof is reported as a C23 extension. The desktop now includes
SDL.hlike the other sources, defines_DARWIN_C_SOURCEon macOS, and
silences only that warning around the two Nuklear headers on a clang that
knows it. Thenuklearandsdl-text-inputsuites pass on macOS again. - Tests cover the desktop path per platform, the data folder per system and
WENA_DATABASE, first-run creation and reopening, both refusals and passed
arguments; the desktop smoke test passes for a created and a reopened board.
Thanks to xet7.
Add a Run option to the build menu
build.shandbuild.batmenu option 2) Run starts the binary that 1) Build
wrote for the current computer,dist/<target>/wenaorwena.exe. Tests,
Server and Tools move to options 3, 4 and 5. The same isrun [ARGS...]as a
named command, which passes its arguments on.- A missing or non-executable binary is refused with how to build it. Tests
cover the file name per platform, both refusals, a real run with its
arguments and exit code, and the menu order.
Thanks to xet7.
Preserve person assignments when moving cards between boards
- Reuse shared member filtering and strict SQLite readers in single-card and
bulk cross-board transfers. Retain members active on the destination board,
preserve assignees, and keep their original ordering positions. - Verify card metadata, both board rosters, and person/actor data throughout the
transfer transaction. Roll back ignored writes, partial transfers, and changes
caused by later writes or triggers. Keep foreign-key enforcement enabled. - Add regression coverage for inactive and absent destination members, empty and
full 2048-person sets, roster overflow, deferred parent updates, rollback and
reopening. Update the roadmap; native person capture adapters, roster
management and person controls remain unfinished.
Thanks to xet7.