fix(release): the Store submit reads the submission with 'get', not 'status'

rc.12-v0.21.7 failed 'Submit the verified Store package' with
StoreError: unreadable submission status: ''.

store.submit parsed 'msstore submission status' as JSON. For a packaged
(MSIX) app that command prints a Spectre markup line ('Submission Status =
...') plus status tables, never JSON, and prints nothing when no submission
is pending (msstore-cli Commands/Submission/StatusCommand.cs). The first real
Store submission therefore always failed. 'msstore submission get' serializes
the submission as JSON (GetCommand.cs) and is already what submit reads after
the upload, so the in-flight check reads that instead.

The test fake now answers 'status' the way the CLI does; with it, main fails
5 tests with the production error.
This commit is contained in:
Teknium committed 2026-10-11 13:31:55 -07:00
1 parent 4eba3ebed1
commit 1fd1827726
2 files changed
+25 -14

No files matched your search

+17 -9
View File
@@ -10,8 +10,8 @@ Green run — ``python -m scripts.releases.store submit <package>`` (Windows
runner, ``msstore`` CLI configured beforehand by
``microsoft/microsoft-store-apppublisher`` + ``msstore reconfigure``):
1. ``msstore submission status <productId>`` — a submission is in flight when
its status is not one of the terminal/failure states
1. ``msstore submission get <productId>`` — the current submission as JSON; it is
in flight when its status is not one of the terminal/failure states
(``None, Published, PublishFailed, Canceled, CertificationFailed,
PreProcessingFailed, CommitFailed``).
2. ``msstore submission delete <productId> --no-confirm`` — only when one is
@@ -97,19 +97,27 @@ def _cli_run(argv: list[str]) -> str:
return result.stdout
def _has_in_flight(status_output: str) -> bool:
def _has_in_flight(submission_output: str) -> bool:
"""Whether ``msstore submission get`` names a submission that is not yet decided.
``submission status`` is no use here: for a packaged (MSIX) app it prints a Spectre
markup line (``Submission Status = ...``) and status tables, never JSON, and prints
nothing at all when the app has no pending submission (msstore-cli
Commands/Submission/StatusCommand.cs). ``submission get`` serializes the submission
as JSON (GetCommand.cs), and it is what ``submit`` already reads below.
"""
try:
status = json.loads(status_output)
submission = json.loads(submission_output)
except json.JSONDecodeError:
raise StoreError(f"unreadable submission status: {status_output!r}")
if not isinstance(status, dict) or "status" not in status:
raise StoreError(f"unreadable submission status: {status_output!r}")
return status["status"] not in _NOT_IN_FLIGHT
raise StoreError(f"unreadable submission: {submission_output[:200]!r}")
if not isinstance(submission, dict) or "status" not in submission:
raise StoreError(f"unreadable submission: {submission_output[:200]!r}")
return submission["status"] not in _NOT_IN_FLIGHT
def submit(package: str, *, product_id: str, run=_cli_run) -> dict:
"""Submit ``package`` with auto-publish off, clearing any in-flight one."""
if _has_in_flight(run(["msstore", "submission", "status", product_id])):
if _has_in_flight(run(["msstore", "submission", "get", product_id])):
run(["msstore", "submission", "delete", product_id, "--no-confirm"])
run(["msstore", "publish", package, "--appId", product_id, "--noCommit"])
submission = json.loads(run(["msstore", "submission", "get", product_id]))
+8 -5
View File
@@ -14,15 +14,18 @@ class _Cli:
def __call__(self, argv):
name = " ".join(argv)
if argv[:3] == ["msstore", "submission", "status"]:
# The real CLI prints Spectre markup for an MSIX app, never JSON, and nothing
# when no submission is pending (rc.12-v0.21.7: "unreadable submission status: ''").
self.events.append(("status", name))
return json.dumps(
{"status": "Certification"} if self.pending
else {"status": "Published"})
return "Submission Status = Certification\n" if self.pending else ""
if argv[:3] == ["msstore", "submission", "get"]:
self.events.append(("get", name))
uploaded = any(kind == "submit" for kind, _ in self.events)
# Before the upload: the last submission (in flight or published). After: the new draft.
status = "PendingCommit" if uploaded else ("Certification" if self.pending else "Published")
return json.dumps({
"targetPublishMode": "Immediate", "friendlyName": "Submission 2",
"listings": {}})
"status": status, "targetPublishMode": "Immediate",
"friendlyName": "Submission 2", "listings": {}})
if argv[:3] == ["msstore", "submission", "delete"]:
self.events.append(("delete-pending", name))
return ""