Commit Graph
10 Commits
Author SHA1 Message Date
winewill b8050f0251 fix(desktop): finish the review items the first pass missed
Three comments in the same review round went unread and still applied.

A failed tag push left the local tag in place, so the printed recovery
`git tag … && git push …` short-circuited on "already exists" and never
pushed. The result now carries the commands still outstanding, and the
tests cover a failed push and a failed tag separately.

Automatic numbering caught every error from resolving the upload
destination, which turned a misconfigured destination into silent local
numbering that can reuse a published index. It now checks whether a
destination is configured at all and lets an invalid one fail, and the
remaining catch names the error it reports.

`pnpmCommand` fell back to a bare `pnpm`, which on Windows is the batch
shim spawnSync cannot start — the failure this branch exists to fix. It
says so instead, and keeps the fallback where a shim is executable.

The afterPack regression this branch introduced earlier reached review
because nothing exercised that hook: one spec calls it directly for an
ordinary build, a prepared qualification runtime, and a build version,
and it fails when the expected version collapses back to one value.
2026-09-21 16:37:50 +08:00
winewill 1b6451a647 fix(desktop): follow the documented release version rules
Review found that `apps/desktop/README.md#release-versions` and the
2026-09-16 version-derivation note already specify this convention, and
that three of their requirements were reversed without saying so. The
rules themselves are right; what was wrong was leaving them undocumented
and rejecting one of the forms they prescribe.

A stable base takes `-test.YYYYMMDD.index`, which validation refused
because such a version ranks below its base. That ordering is the point:
the form belongs to a test feed that never serves the production
release. Both READMEs, the older note, and a new note now record which
requirements this change reverses and why.

Three defects the review found, each reproducible:

- `afterPack` compared the bundled runtime against the product version,
  which broke installed-update qualification: that flow passes a runtime
  whose version was deliberately rewritten. The expected version is now
  a parameter the preparer supplies, and `verifyDesktopRuntime` says
  "bundled X is not the expected Y" rather than naming Electron.
- Upload could only learn the published version from a shell variable,
  conflicting with "release fields come only from the target file". It
  reads the completion record packaging wrote, and a mismatch now prints
  the version that record holds.
- Automatic numbering read one listing page and one fixed directory. It
  now follows every page, discards a listing it could not finish rather
  than reusing an index that would overwrite a published installer,
  bounds the request through the client's own timeout, and reads the
  directory an unsigned build actually writes.

Also: `npm run` and `yarn run` set `npm_execpath` too, so the pnpm
resolution checks the path names pnpm; the argument separator can arrive
after a run script's preset arguments, not only first; and the toolchain
probe, parser, build commit, and tarball readers now have specs.
2026-09-21 16:04:08 +08:00
winewill 766eee63eb fix(release): run pnpm and tar portably on Windows
spawnSync cannot start the pnpm .cmd shim without a shell, so the bump
step's lockfile refresh failed with ENOENT on Windows after rewriting
every manifest. Resolve pnpm to a JavaScript entry executed by the
current Node: the run-script's npm_execpath when present, otherwise the
workspace's own pnpm dependency (located on disk because pnpm's manifest
does not export its bin entry).

GNU tar parses the colon in an absolute Windows path as a remote-host
separator and aborts, so the tarball readers now run tar in the
tarball's directory and pass only its file name.
2026-09-21 13:30:12 +08:00
imccyu b342b09401 chore(release): drop the unused synchronous runner 2026-08-26 13:23:41 +08:00
imccyu f18ab429e4 ci(release): pack rehearsal tarballs concurrently 2026-08-26 12:46:17 +08:00
Turtle 6b3e971805 docs: remove implementation narration from prose 2026-08-21 22:22:23 +08:00
imccyu 0e50fa290c fix(release): state what the echo helper does, and drop two dead claims
Three corrections from review, none of which change behaviour.

attemptStreaming promised output "as the command produces it", which
spawnSync cannot do: it returns only after the child exits, and the two
streams are echoed one after the other, so their interleaving is lost.
For an npm publish that is visible — notices go to stderr while the
`+ name@version` confirmation goes to stdout, so the confirmation prints
first. The helper is now attemptEchoed and its contract says buffered,
echoed after exit, stdout before stderr; live progress would need an
asynchronous spawn with data listeners.

The traversal comment claimed a node on the stack is a cycle only peer
edges can form, and that skipping it drops just that edge. The cycle does
carry a peer edge, because the install edges were proved acyclic a moment
earlier, but the back edge that reaches the stacked node need not be the
peer one — which is what the post-condition exists to catch, so the
comment now points at it instead of asserting an invariant the traversal
does not have.

The `if (placed.has(member.name)) return` after leaving the stack was
unreachable: a re-entrant visit returns at the top guard while the member
is on the stack, so it can never be placed by the time the recursion
unwinds.
2026-08-14 16:10:06 +08:00
imccyu 70eb76eaec fix(release): keep npm's own output in the publish log
Retry classification needs npm's failure text, so the publish call captured its
streams instead of inheriting them. That silenced npm on the success path: the
log lost the tarball contents, the notices, and the '+ name@version'
confirmation for every package.

Pipe the streams and echo them, so the log shows what npm reported and the
caller still gets the text it classifies. The registry probe behind it keeps its
streams captured, since its JSON and its E404 are internal queries rather than
progress.
2026-08-14 16:10:06 +08:00
imccyu d9dcf5a484 fix(release): close the review findings on the release sequences
The root manifest carries the dsh family version. bump writes it with the
members, because the workspace constraint requires them to match, and that
constraint now accepts a prerelease segment: without both, release:dsh 0.0.2
left the root behind and 0.0.1-rc.1 could satisfy neither check.

The Landlock workflow no longer passes --access public, which overrode the
restricted publishConfig this repository just adopted for those packages.

Vendored change detection reads build inputs when a package publishes build
output, and vendor/cordis publishes the src its export map already pointed at:
its lib/ is untracked, so a real source edit read as 'nothing changed' and the
next publish would fail on a version whose bytes moved. The next version also
takes the last published version as its baseline, so a re-sync that restores a
lower upstream version cannot recompute a version already on the registry, and
bump confirms the registry carries what the newest tag names.

Tag prefixes are constructed rather than recovered from a full tag, which a
hyphenated version defeated. Pack runs group per ref so concurrent pull requests
stop displacing each other, the publish job carries the global group, and the
unused id-token permission is gone.

Every release script sits behind an entry guard, which is what lets the pure
judgements carry tests: tag naming, publish order and cycle reporting, version
arithmetic, payload policy, and the change judgement.

The Agent Note moves to implemented and states what shipped: one probe command,
the registry confirmation that now exists, and byte reproducibility recorded as
assumed rather than measured.
2026-08-11 01:26:36 +08:00
imccyu 787443b13f fix(release): verify the packed install against the framework it peers on
The harness packages declare the vendored framework as a peer, so installing
only the dsh tarballs left npm resolving @deepseek-ai/cordis from a private
registry the credential-free pack job cannot reach. The verification now takes
several pack directories and installs every tarball in them, and the dsh
workflow packs the vendored family for that purpose while still publishing only
its own set.

The verification also reads what each tarball declares instead of what the
checkout says, which is what let the process and tarball helpers become one
home each - the three copies of a spawn wrapper were a duplication finding.
2026-08-11 00:51:02 +08:00