Skip to content

Sync ako/mxcli: install protected .mxmodule packages (#1755 + follow-up) - #1759

Merged
ako merged 19 commits into
mendixlabs:mainfrom
ako:main
Nov 6, 2026
Merged

ako merged 19 commits into
mendixlabs:mainfrom
ako:main

Conversation

@ako

@ako ako commented Nov 6, 2026

Copy link
Copy Markdown
Collaborator

Syncs ako/mxcli:main into upstream: 2 commits since #1756 — #1755 as submitted, plus a follow-up on top of it.

Marketplace: protected modules shipped as .mxmodule

  • Install protected modules (from fix: install protected modules shipped as .mxmodule (#1754) #1755, by @MendixMau). A protected module package carries its model as one BSON tree instead of an SQLite .mpr, so install failed with "file is not a database", and mx module-import refuses it. The tree is split into units and written into the reference project with the raw-unit writer; protection settings are copied unchanged.
  • Give that reference project what mx module-import would. The reference project is also read for the package's Java and JavaScript sources (describe java action / describe javascript action), and the first commit wrote only the units, so marketplace diff and update would report every action of such a module as changed locally (marketplace update --to refuses without --force, citing local edits nobody made #1441). The package's declared files are now written beside the units. The units are not converted to the project's Mendix version, so a tree saved with a newer Mendix than the project is refused.

Fixes #1754

stagknee and others added 19 commits October 26, 2026 13:28
…ut a propertyGroup (mendixlabs#1632)

Every Marketplace Calendar written by mxcli failed a plain `mx check` with
CE0463 "The definition of this widget has changed". The Calendar has no
embedded template, so its Type is generated from the .mpk, and its
toolbarItems object list declares its sub-properties directly under
<properties>, each with a <category> element. modelsdk/widgets/mpk read
only <properties><propertyGroup>, so toolbarItems had no Children and was
stored with ValueType.ObjectType null.

The parser now reads both shapes, as sdk/widgets/mpk already does; a
direct sub-property takes its category from its own <category>. On an
11.12.5 app the stored Calendar equals a copy rewritten by
`mx update-widgets` (ids stripped), and the object-list widgets of
doctype-tests/32 are stored byte-identical to before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A protected module package carries its model as one BSON tree instead
of an SQLite .mpr, so install failed with "file is not a database" and
mx module-import refuses it. Split the tree into units and write them
into the reference project with the raw-unit writer; protection
settings are copied unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The protected-module path in PackageProject wrote only the units. The
reference project is also read for the package's Java and JavaScript
sources (DESCRIBE JAVA/JAVASCRIPT ACTION), so marketplace diff and update
would report every action of such a module as changed locally
(mendixlabs#1441). Write the package's declared files beside it,
as mx module-import does.

The units are not converted to the project's Mendix version, so refuse a
tree saved with a newer Mendix than the project. Split units only out of
modules and folders, read the package entry and module name once, and
keep the refcache comment true for a reference that stays MPR v2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QiMsnXa9crge2qnSk9S7Zn
Install protected modules shipped as .mxmodule (mendixlabs#1755, with review fixes)
…red without a propertyGroup

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QiMsnXa9crge2qnSk9S7Zn
…bprops

Read an object property's sub-properties declared without a propertyGroup (mendixlabs#1633)
widgetToMap turned every int32/int64 into float64 and mapToWidgetDoc never
turned them back, so a synced widget was written with doubles throughout,
including a text box in its slot whose MaxLengthCode -1.0 Mendix reads as
unlimited (CE6510).

Stored int32/int64 now pass through the map form unchanged; a stored double
is tagged so it stays a double; a bare float64 is a number the template
pipeline made and is written as int32 (int64 past its range), as create does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011oK82tQYYsMeM1r2ihkNch
The fork had 90 open mirrors while upstream showed about 130 open issues.
The difference is upstream tickets the fork already closed as fixed:
mirror.py leaves closed mirrors alone, and the triage session cannot read
upstream, so nothing listed which upstream tickets are waiting to be
closed.

mirror.py, which can read upstream from GitHub Actions, now labels a
mirror `upstream-open` while it is closed here as completed and its
upstream original is still open, and removes the label when upstream
closes it or the mirror is reopened. It confirms an upstream closure
with a direct lookup before removing the label, so a short upstream
listing cannot strip them all. The run summary lists the upstream
numbers as `fixed_here_open_upstream`, and the triage board lists the
labelled mirrors.

test_mirror.py adds seven scenarios (H-N); the script on main fails
all seven and passes the existing seven.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NTDRrgJhKKmSUnBFaDUw62
Label mirrors fixed here whose upstream ticket is still open
fix(widgets): widget sync keeps stored integer widths (#1976)
…write (#1980)

create constant wrote ExportLevel "" where Studio Pro writes "Hidden". mx
check accepts it, but mx diff crashes on a "" copy against a "Hidden" one
(exit 129, measured on 11.14.0), which takes git merge's report with it.
create or modify constant also turned a stored API/Hidden into "".

constToGen defaults to Hidden like every other writer; UpdateConstant keeps
the stored level via keepStoredExportLevel, which also repairs a stored "".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011oK82tQYYsMeM1r2ihkNch
fix(constants): write ExportLevel Hidden, keep the stored level on rewrite (#1980)
…report (#1981)

When either side's mx diff failed, the property-level report was skipped
without a word. propertyReport now takes each side's error and is always
called: a failed side prints "(diff unavailable: <why>)" on one line, the
other side its changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011oK82tQYYsMeM1r2ihkNch
fix(git-merge): report a failed mx diff side instead of dropping the report (#1981)
A merge conflicting on a text file and the model: the run stopped on the
text file, the human resolved and staged it, the re-run hit
ManualResolutionRequired (exit 2) and aborted - and `git merge --abort`
reset the index with the resolution in it. --plan then re-merged, met the
text conflict unresolved, wrote the model and failed at the commit on
"unmerged files": half done, the resolution gone (mendixlabs#1751).

- The exit-2 path records each staged non-model path in the plan template
  (`resolved`: path + index blob, or deleted); the blob is already in the
  object store, which the abort does not prune.
- --plan puts each recorded resolution back on a path that conflicts again
  and stages it, then stops on any non-model conflict still open - before
  the stale check, the engine and the model - with the plain run's
  "resolve by hand" message and the merge left in progress.

TestGitMerge_TextResolutionSurvivesTheAbortAndThePlan runs the reporter's
three steps with real git and a fake engine: before the fix step 3 failed
with the reported "unmerged files" commit error; now the merge commit holds
the hand resolution. TestGitMerge_PlanStopsOnAnOpenTextConflict: the engine
does not run and the merge stays in progress. Stubbing the restore makes the
new check stop the plan (resolution lost, nothing half-written); stubbing the
check lets the engine run. The real-mx git merge integration tests (11.12.6)
pass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011oK82qrr1WnXxq1eRn7qRJ
…rioritization-24rqgv

# Conflicts:
#	CHANGELOG.md
…24rqgv

fix(git merge): keep text resolutions across the exit-2 abort
@ako
ako merged commit 3e320d1 into mendixlabs:main Nov 6, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

marketplace install fails on protected modules shipped as .mxmodule ("file is not a database")

4 participants