Commit Graph

2 Commits

Author SHA1 Message Date
Leo aeb44c712b fix(88): 撤回「產生端吐裸號」的宣稱——那個 v 是版本線判別器,不能單獨拿掉
總管複驗退回一格(`inkstone/arcrun-rag#88#issuecomment-3082`),退得對。
我照他要的兩條路去查,結論是**選 B,而且原本那個改動本身有 bug**。

## 兩件事要分開講

**① 總管的事實宣稱有一處錯,但他看到的現象是真的**
「這條分支一行都沒動 daemon-version.py」— 不對,上一個 commit 動了 37 行,
含 `version = "v%d.%d.%d"` → `"%d.%d.%d"`。他跑 `daemon-version.py` 得到 `v0.18.29`
也是真的:當時的過渡規則讓「重打已發佈的版本」沿用原本寫法。
⇒ 他跑對了指令、看到真東西,只是把原因歸成「沒改」。

**② 但我的改動確實有 bug,而且比他指出的更嚴重**
`^## v` 這條判斷式有**四份各自為政的拷貝**(daemon-freshness/daemon-in-bundle-gate/
ship.mjs daemon-sync/daemon-version.py),三份只認帶 `v` 的。
產生端一旦戳出 `## 0.18.30(…)`,那三份**不會報錯**,而是往下比對到更舊的
`## v0.18.29(…)` ⇒ **打包出 0.18.30 的執行檔,manifest 卻宣稱是 v0.18.29。**
版本號說謊,靜默,21 站全綠。上一個 commit 就埋著這顆。

## 為什麼不是把三份放寬成 `v?`(我試了,當場被測試擋下)

🔴 **那個 `v` 目前身兼「哪一條版本線」的判別器。**
放寬後 daemon 的閘開始把雲端那條 `## 1.4.47(…)` 當成 daemon 版本撈走
⇒ `daemon-in-bundle-gate.test.mjs` ①⑮⑯ 轉紅,而它們釘的正是 D95 第二輪剛修好的
「出貨線指到錯的 changelog 卻安靜放行」。`daemon-notes.changelogRelFor()` 也用 `/^v/`。

⇒ 「不要 v」要落到產生端,得**先給那些閘一個替代判別器**
  (建議拿 `DAEMON_LINE` 比對,例 `^## v?0\.18\.\d+(`,同時擋「錯的檔」與「錯的線」)。
  那要動 `topReleasedVersion()` 等對外簽章、跨 installer/ 與 collector/,
  **與正在進行的 collector 拆 repo 相衝** ⇒ 不在這條分支做。

## 這個 commit 做了什麼

- 產生端**恢復原行為**(一律吐 `v`):不留「產生端裸號+閘只認 v」那顆靜默炸彈
- 四份拷貝**收成一份**(`daemon-notes.DAEMON_RELEASED_RE`,維持嚴格版)
  ⇒ **零行為變更**,但哪天要改格式只需改一個地方,而不是記得改四個
- 把「為什麼還不能改裸號」釘成一支會說話的測試(`daemon-version.test.mjs` ⑤⑥)
  ——不是註解,是紅燈
- 兩處註解寫清楚接手要先做什麼

**上一個 commit 的另外兩格(release 掛成品、內外對應)未受影響,總管已複驗通過。**

測試:installer 252/252、collector 6/6。
2026-08-18 15:25:22 +08:00
Leo 2e26528bc9 feat(version): 對外號真的不帶 v + release 掛得動成品 + 內外對應由機器產生(arcrun-rag#88)
leo 2026-08-18 當場抓到「剛剛不是說不要 v?」——實查確認不是措辭問題:
規約寫在 wiki,而**產生號碼的那條路照舊帶 v**。這輪修的是產地與載體。

① 對外號從**產生端**就是裸的
   `daemon-version.py` 是 daemon 那條線唯一的版本產生器,一路長到
   產物檔名(Arcrun-<版本>.dmg)、manifest.daemon.version、/api/latest。
   - 新戳的版本一律裸號;`RELEASED_RE` 加 `v?` 讀得懂歷史
   - 🔴 重打同一版**沿用 changelog 上原本的寫法**:selfupdate.go 的
     newerThanCurrent() 是字串不等於就提示更新 ⇒ 把 v0.18.28 改吐成 0.18.28
     會讓每台已安裝的機器收到一個內容相同卻宣稱是新版的**假更新**。
     規約會自己過期:頂上那段變裸號之後,重打路徑吐的也是裸號。
   - 實測:真實 changelog +一段未發佈 → 產生器吐 `0.18.30`(不是 v0.18.30)

② release 掛得動真的成品(本輪的硬前置)
   leo:「assets 都寫 source code,這兩個附檔實際是什麼?是 dmg 還是 go?」
   ——那是 Gitea/GitHub 自動產生的整包 repo 快照。實測既有 release 的
   attachment 數是 **0**,坐實那兩個附檔沒有一個是成品。
   - gitea/github-release.mjs 各補 uploadReleaseAsset/listReleaseAssets
     (兩邊 API 形狀不同是 API 本身的差別,不硬套成同一種)
   - release-lines.mjs 讓**每條版本線各自宣告**自己的成品(assetKeys);
     daemon 線明列 mac/win/msix,**排除釘在 0.15.7 的兩筆歷史遺留**
     ——照「有 file 欄就掛」會把舊檔掛上新版頁面,正是本輪要治的病
   - ship.mjs 建完 release 後掛檔,並**回頭查證**附件真的在頁面上;
     缺任何一個就擋(不留「點下去沒東西」的版本頁)

③ 內外對應由機器產生,不再是總管手寫
   leo:「對應關係記在該次發佈的 release note,不靠號碼本身編碼」
   - 新增 internal-version.mjs:`RAG-20260818-001-<commit7>`
   - 🔴 `formatInternalVersion` 收到空的 artifacts 直接丟例外
     ⇒ **算不出一個沒有成品的內部號**(leo:「內部每次就要出貨 bundle 的版本」)。
     ops-facts 原本記著「這件事目前靠自律,沒有機械閘」——這就是那道閘
   - 序號從**既有 release 的事實**算,不養會漂的帳;tag 與內文都掃
     (08-17 那兩筆內部號寫在 tag_name 上,只掃內文當天會從 1 重編、無聲撞號)

紅線遵守:既有 tag/檔名一個都沒回頭改;沒寫 GitHub(②③ 實測都在 Gitea);
沒部署、沒推 main、沒自己併分支。演練建的 release 與 tag 都已刪除複驗。

測試:installer 252 支全綠(原 233 +新 19);collector 產生器新增 6 支全綠。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 15:13:00 +08:00