Skip to content

Commit 3a6c06a

Browse files
ndemiancclaude
andcommitted
docs(releasing): commit the version-stamp check and the auto-update warning
These 38 lines had been sitting uncommitted in the working tree across several releases, surviving only because nobody ran `git checkout -- .`. They document two things the runbook needs and neither is guessable from the scripts: 1. VERIFY THE VERSION STAMP (§3). The app must report levelcodeVersion, not the Code-OSS base — and this fails SILENTLY, so it needs an explicit per-release check. Includes the one-liner, what each field must be, and a table mapping the two build log lines to "good" vs "fix before publishing". 2. PUBLISHING IS DEPLOYING (§5). With LEVELCODE_UPDATE_FEED_SIGNED=1, publishing a release makes every existing install download and apply it at its next check. No staged rollout, and the rollback lever stops propagation but cannot un-update anyone who already took it. Plus a curl to confirm the feed actually picked the release up. I did NOT write this prose — it is pre-existing work by the repo owner. My part was verifying it before enshrining it, since committing an inaccurate runbook is worse than leaving it uncommitted: - both quoted log lines exist verbatim (build-macos.sh:101 and :105) - stamp-levelcode-version.mjs does write levelcodeVersion and deliberately leaves `version` at the Code-OSS base for engines.vscode, exactly as the note claims - the feed path and the "LevelCode Updater" user-agent match what production nginx actually logs Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 8140280 commit 3a6c06a

1 file changed

Lines changed: 38 additions & 1 deletion

File tree

docs/RELEASING.md

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ export NOTARY_PROFILE="levelcode-notary"
5353

5454
```bash
5555
./scripts/bootstrap.sh # first time / after an upstream bump (clone + brand + patch + npm ci)
56-
./scripts/build-macos.sh # → VSCode-darwin-<arch>/LevelCode.app, then auto-strips proprietary MS/Copilot code from the app
56+
./scripts/build-macos.sh # → VSCode-darwin-<arch>/LevelCode.app; strips proprietary MS/Copilot code, then stamps the release version (§3)
5757
./scripts/make-dmg.sh # de-Microsoft (defensive) → sign (Developer ID) → dmg → notarize → staple → verify
5858
```
5959
With `CODESIGN_IDENTITY` + `NOTARY_PROFILE` set, `make-dmg.sh` runs the whole signed+notarized pipeline;
@@ -75,6 +75,26 @@ find VSCode-darwin-arm64/LevelCode.app \( -path "*@github/copilot*" -o -path "*m
7575
\( -name "*.node" -o -name "*.dylib" -o -name "mxc-exec-mac" \) -print # → prints NOTHING
7676
```
7777

78+
Confirm the app reports **its own** version rather than the Code-OSS base — this **fails silently**, so
79+
check it every release:
80+
```bash
81+
python3 -c "import json;d=json.load(open('VSCode-darwin-arm64/LevelCode.app/Contents/Resources/app/product.json'));print(d.get('levelcodeVersion'),'|',d.get('version'),'|',d.get('commit','')[:7])"
82+
# → 0.8.1 | 1.126.0 | 07b7341
83+
# ^ the release version ^ MUST stay 1.126.0 (extensions' engines.vscode is checked against it)
84+
```
85+
A **missing `levelcodeVersion`** means `build-macos.sh` could not resolve a tag (`git describe --tags`
86+
failed) and fell back — the update tooltip and About will then report `1.126.0`, the upstream base, which
87+
is exactly the confusion this stamp exists to prevent. The build log distinguishes the two:
88+
89+
| Log line | Meaning |
90+
| --- | --- |
91+
| `[build] Stamping the LevelCode release version (v0.8.1) …` | Good. |
92+
| `[build] WARN: no reachable git tag — skipping the release-version stamp.` | **No stamp** — fix before publishing. |
93+
94+
An off-tag build is stamped `0.8.1-3-g1a2b3c4` on purpose (see `scripts/stamp-levelcode-version.mjs`): a
95+
build that isn't a release must not impersonate one. A release build sits on the tag and gets a clean
96+
`0.8.1`, so a suffix here means you are not building what you think you are.
97+
7898
Build **both architectures** on matching hardware (Apple silicon → `arm64`, Intel → `x64`) to ship both dmgs.
7999

80100
## 4. Publish
@@ -92,10 +112,27 @@ from **levelcode.ai/download**.
92112

93113
## 5. The update feed
94114

115+
> ⚠️ **Auto-update is LIVE — publishing is deploying.** `LEVELCODE_UPDATE_FEED_SIGNED=1` is set in
116+
> production, so a published release is no longer just *announced*: the built-in Squirrel updater
117+
> **downloads and installs it on every existing install** at that install's next check. There is no
118+
> staged rollout and no percentage gate. The rollback lever (below) stops it propagating further but
119+
> **cannot un-update anyone who already took it**. Finish §3 on a real Mac *before* `--draft=false`.
120+
>
121+
> This changed with v0.8.0 — the first release to carry signed `.app.zip` assets. Everything published
122+
> before that stayed notify-only regardless of the flag, because the feed refuses to hand Squirrel a
123+
> release that has no installable asset for its arch.
124+
95125
Publishing the GitHub release **is** the announcement — `Levelcode::EditorReleaseFeed` (thin.ly) reads
96126
`releases/latest` and serves `/api/update/{target}/{quality}/{commit}`. There is no feed file to
97127
hand-maintain per release.
98128

129+
Confirm the feed picked the release up (it caches for 5 minutes):
130+
```bash
131+
curl -s -H "User-Agent: LevelCode Updater" \
132+
https://levelcode.ai/api/update/darwin-arm64/stable/deadbeef | python3 -m json.tool
133+
# url must end in LevelCode-arm64.app.zip (NOT a /releases/tag/ page), and productVersion must be the new one
134+
```
135+
99136
Two assets, **not** interchangeable:
100137

101138
| Asset | Consumer |

0 commit comments

Comments
 (0)