Fold hosted-publish learnings: split publish-to-hosted.md, correct upload + mode enum#58
Merged
Merged
Conversation
Justinvolved
force-pushed
the
fold/publish-to-hosted
branch
from
July 13, 2026 11:43
5709919 to
fd87818
Compare
…load + mode enum A second local-to-hosted publish surfaced a serializer gap with an outsized blast radius: custom product fields are column-backed (EcomProductField = a column on EcomProducts) but the engine's schema-sync only walks EcomProductGroupField, so a deserialize lands field definitions whose columns do not exist. That 500s every product read and makes every Full index build report status:ok while indexing zero documents — install-wide, including repositories the demo never touched. The pre-flight (create the fields on the target before the first deserialize), the resulting deadlock, and the duplicate-SystemName trap that reproduces the same zero-document failure are now documented. online-mode.md had grown to cover two different jobs. The publish playbook moves to a new references/publish-to-hosted.md, extended with the id collisions that bite when publishing onto a stock Swift install (a variant group whose target twin is a colour group swallows the demo's options and renders no selector), index portability (the definition travels, the built segments do not), and derive-on-save item fields that a deserialize cannot preserve. Two corrections to existing guidance. Upload: allowOverwrite=true is an undocumented form field that makes the endpoint overwrite; the prior delete-before-upload workaround is replaced, and success is model being a list, never status:ok — a refused batch reports ok and writes nothing. Restart: the CloudHosting control files are a Dynamicweb Cloud affordance, not a property of every hosted install, so the flat claim that a cloud install can be restarted is now qualified with a consumed-file check. serializer-reference.md taught "mode": "Deploy"|"Seed" as the current predicate enum. Engine 0.8.x rejects those (ConfigLoader.ValidatePredicates: valid values are Replace, Merge) and moves the run's mode into the JSON body. The enum is now version-scoped, and GET /Admin/Api/SerializerSettings is prescribed as the one-call config-validity probe — a config authored for the wrong engine major 500s every Serializer call, including that read-only one. deserialize-flow.md's 0.6.9-stamped flow gains a pointer for 0.8.x callers.
Justinvolved
force-pushed
the
fold/publish-to-hosted
branch
from
July 13, 2026 12:13
fd87818 to
85f16c6
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What surfaced this
A second local→hosted publish. One serializer gap had an outsized blast radius, and two pieces of existing guidance turned out to be wrong.
The headline — a silent, install-wide index kill
Custom product fields are column-backed:
EcomProductFieldis a physical column onEcomProducts. ASqlTablepredicate deserializes the definition rows faithfully, and nothing creates the columns — the engine's schema-sync only walksEcomProductGroupField.The target then lands with field definitions whose columns do not exist, and:
titleis the bare field name;Fullindex build returnsstatus: okwhile indexing zero documents — install-wide, including repositories the demo never touched;Only the first of those looks like an error.
BuildIndexreportingokis what makes this expensive.It also deadlocks: once the definitions exist without columns, the field can be neither dropped (
ALTER TABLE DROP COLUMN failed because column '<F>' does not exist) nor created (system name already in use). The one exit — re-saving the existing field provisions the column — is documented, along with the duplicate-SystemName trap that reproduces the same zero-document failure if you create the field via the API and then deserialize.Pre-flight fix: create the product fields on the target with
ProductFieldSavebefore the first deserialize.The split
online-mode.mdhad grown to cover two different jobs (build on a hosted install vs migrate a local demo onto one) and was at the size guideline. The publish playbook moves to a newreferences/publish-to-hosted.md, extended with:EcomGroupRelations(the target's hierarchy wins unless you ship it) and relation rows that silently re-attach the stock catalog.IsDryRunbefore every hosted deserialize.SqlTablepredicate, though no shipped example config includes them.Corrections to existing guidance
allowOverwrite=true— an undocumented form field that works. Success ismodelbeing a list, neverstatus: ok: a refused batch reportsok, writes nothing, and one pre-existing name drops the batch's new files too.recycle.txt/restart.txtand never acted on them — confirm the file is consumed, or rung 3 doesn't exist on that host.serializer-reference.md:"mode": "Deploy"|"Seed"is the current enumReplace/Merge—Deploy/Seedare rejected, not aliased (ConfigLoader.ValidatePredicates) — and the run's mode moves into the JSON body. A config authored for the wrong engine major 500s every Serializer call, including the read-only settings query, soGET /Admin/Api/SerializerSettingsis now the prescribed one-call config-validity probe.deserialize-flow.md's 0.6.9-stamped two-pass?mode=flow is still correct for 0.6.9 and gains a pointer for 0.8.x callers.Gates
python scripts/validate-skills.py→ 0 errors, 0 warningsskills/for theDeploy/Seedclaim — three hits, all resolved (one was already correct, one corrected, one version-pointed)metadata.version4.8.0 → 4.9.0 (minor — new reference), README + CHANGELOG updated in the same commit