docs: 版本說明頁刪除,改連 GitHub 版本發佈(arcrun-rag#41)
leo 2026-08-17:「這個頁面刪除。」 (同一件事 08-09 就講過:「不要同步,docs 的版本說明直接連回 github 的版本發佈」, 那時記在該檔檔頭當待辦,理由是「等 releases 累積出足夠版本歷史」——現有 9 筆,理由失效。) 使用者要看版本紀錄 → github.com/youlinhsieh/arcrun-rag/releases。文件站不再自己維護一份。 ── 🔴 動手前發現的事:那一頁不只是一頁 ────────────────────────────── `docs-site/src/content/docs/help/changelog.md` **同時是兩個東西**——文件站的一頁, 以及**雲端引擎 `1.4.x` 的出貨原稿**(`installer/scripts/daemon-notes.mjs` 的 `CHANGELOG_REL`, 被 `ship.mjs` 的 docs-changelog/release-record 與 `github-release.mjs` 讀)。 直接 `rm` 會讓雲端那條線的 GitHub/Gitea 版本發佈點進去變空白。 ⇒ 頁面刪掉,**原稿搬去 repo 根的 `CHANGELOG.md`**(旁邊就是根的 `RELEASE_LINE`), 形狀與桌面版那條線一致:`collector/CHANGELOG.md` + `collector/DAEMON_LINE`。 `collector/CHANGELOG.md` 一個字都沒動。 ── 投影機制整套拆掉(0fb72ae,D95 第四輪,昨天才併進 main)────────── 它存在的唯一理由是把 daemon 段落渲染回這一頁。頁面沒了,它就是沒人用的機制: · `docs-site/remark-daemon-changelog.mjs`(整支) · `astro.config.mjs` 的 import 與 `markdown.remarkPlugins` · `package.json` build 的 `--force`(那是投影的必要條件,不是通用旗標) · `collector/.../daemon-notes.mjs` 的 `releasedSections()`/`releasedSectionsFromFile()`/`RELEASED_HEADING` · `collector/.../daemon-notes.test.mjs`(4 支全是投影的演練) `daemon-notes.mjs` 其餘匯出(notesForVersion/checkNotes…)是出貨線在用的,留著。 ── 舊網址留一條轉址,不直接 404 ────────────────────────────────── 那個網址掛在側欄上、也印在 landing「這一版改了什麼」旁邊,已隨 landing 部署到使用者 瀏覽器裡。repo 內的連結本輪都改成直接指 GitHub(landing/docs 首頁/側欄), 所以轉址不服務任何內部連結,只接書籤與舊 HTML。它是 `astro.config.mjs` 的一行宣告 (沒有程式、沒有真相源可以漂),而且被 verify-docs 每次出貨夾住 ⇒ 不是要維護的機制。 ── ⚠️ 一次真的降級,標在這裡不藏 ──────────────────────────────── `verify-docs.mjs` 原本斷言「線上那一頁有這兩個版號」——沒有頁面就沒有東西可查。 改成斷言「那條轉址還在」(=線上這顆確實是這份原始碼建的)。 **舊斷言抓得到「內容停在上一版」,新斷言抓不到。** 差額由 `release-record` 站承接: 每條版本線都要有一筆版本發佈、內文抽不到就中止——那一站有牙齒且更早跑。 `docs` 站的 ① 那道「這一版寫了嗎」照舊每個目標都問(D65:不准跳)。 實測 · 建置產物:`1.4.4x`/`v0.18.2x` 命中 0 個檔;`dist/help/changelog/index.html` =轉址頁(meta refresh+canonical+a href 全指 releases) · 兩種網址(astro preview):`/docs/help/changelog` 與 `…/changelog/` 皆 200, 內容同一份轉址頁,版本號命中各 0 · 站內死連結:指向該網址的 href 0 條;pagefind 11 個 fragment 含 changelog 者 0;sitemap 未列 · 產生鏈完整:`1.4.47`→根 CHANGELOG.md(摘要+4 行內文)/`v0.18.29`→collector/CHANGELOG.md (摘要+6 行內文)/`1.4.29`→根(6 行);不存在的版號回 null · `node --test installer/scripts/*.test.mjs` 233 支全綠 (238→233:-4 投影演練、-1 htmlText,兩者的實作都已移除) · 建置那句 `/404.htmlEntry docs → 404 was not found.` 是既有行為—— 拿掉 redirects 重建仍出現,與本輪無關 Refs: inkstone/arcrun-rag#41 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+6
-3
@@ -7,9 +7,12 @@
|
||||
> 那條臍帶讓 `collector/` **沒有資格被搬成獨立 repo**,也讓「源碼→產出物」多了一道要記得的扭曲。
|
||||
> 現在它與 `DAEMON_LINE`、`daemon-version.py` 住在同一棵樹底下,`collector/` 自己就算得出自己的版本。
|
||||
>
|
||||
> 🔴 **雲端(Arcrun 引擎 1.4.x)的版本說明不在這裡**,它留在
|
||||
> `docs-site/src/content/docs/help/changelog.md`——兩條版本線本來就是兩個產品,
|
||||
> 混在一個檔裡是 D95 要拆掉的那種扭曲。
|
||||
> 🔴 **雲端(Arcrun 引擎 1.4.x)的版本說明不在這裡**,它住在 repo 根的 `CHANGELOG.md`
|
||||
> (2026-08-17 從 docs-site 搬去,同一天 leo 說「這個頁面刪除」)——
|
||||
> 兩條版本線本來就是兩個產品,混在一個檔裡是 D95 要拆掉的那種扭曲。
|
||||
>
|
||||
> 📌 **兩份都不是網頁,是出貨原稿。** 使用者讀的是
|
||||
> [GitHub 版本發佈](https://github.com/youlinhsieh/arcrun-rag/releases),由 `installer/scripts/github-release.mjs` 拿這兩份檔的段落產生。
|
||||
|
||||
## 怎麼出新版(不要手打版本號)
|
||||
|
||||
|
||||
@@ -49,70 +49,6 @@ export function stripMarkdown(s) {
|
||||
.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* 「已發佈」的版本段落長這樣:`## v0.18.29(2026-08-16)`。
|
||||
* 待發佈的那一段標題是「下一版(未發佈)」,**不符合這個形狀** ⇒ 天然不會被投影出去。
|
||||
* 這是刻意的:投影器不必另外認一次「未發佈」,少一條要記得的規則。
|
||||
*/
|
||||
const RELEASED_HEADING = /^##\s+(v\d+\.\d+\.\d+)(?=\D|$)/;
|
||||
|
||||
/**
|
||||
* 把 changelog 切成「只剩已發佈段落」的 markdown。**給文件站投影用。**
|
||||
*
|
||||
* ── 為什麼這件事住在 collector/(2026-08-18,D95 第三輪)─────────────────
|
||||
* 文件站要在建置時把桌面版的更新內容接回 `/docs/help/changelog/` 那一頁
|
||||
* (網址不變、使用者看到的東西不變)。**接的方式必須是「讀本檔」而不是「複製一份」**
|
||||
* ——第一輪把這條線搬進 `collector/CHANGELOG.md` 就是為了拔掉「同一份 changelog 存兩地」。
|
||||
*
|
||||
* 而「哪些段落算已發佈、preamble 要丟掉」是 **changelog 自己的格式知識**,
|
||||
* 不是文件站的知識 ⇒ 解析住在 daemon 這棵樹裡,文件站只負責把結果貼上去。
|
||||
* 方向仍然單向:**根(docs-site)往內伸手拿,collector 不往外伸手。**
|
||||
*
|
||||
* 丟掉的:檔頭那段給維護者看的說明(含「怎麼出新版」與那個 `<二級標題>` 範例)、
|
||||
* 以及任何還沒戳版號的段落。留下的:每一個 `## vX.Y.Z(日期)` 段的原文,一字不改。
|
||||
*
|
||||
* @param {string} changelogText changelog 全文
|
||||
* @returns {{markdown: string, versions: string[]}} markdown=只剩已發佈段落;versions=由新到舊
|
||||
*/
|
||||
export function releasedSections(changelogText) {
|
||||
const lines = String(changelogText).split('\n');
|
||||
const kept = [];
|
||||
const versions = [];
|
||||
let inside = false;
|
||||
for (const l of lines) {
|
||||
// 只有二級標題會切換「現在在不在一個已發佈段落裡」。
|
||||
// `### 小標` 不會(`^##\s` 要求第三個字是空白),所以段落內的結構完整保留。
|
||||
if (/^##\s/.test(l)) {
|
||||
const m = l.match(RELEASED_HEADING);
|
||||
inside = Boolean(m);
|
||||
if (m) versions.push(m[1]);
|
||||
}
|
||||
if (inside) kept.push(l);
|
||||
}
|
||||
return { markdown: kept.join('\n').trim(), versions };
|
||||
}
|
||||
|
||||
/**
|
||||
* 同 `releasedSections()`,但直接讀檔,且**問不出東西就 throw**。
|
||||
*
|
||||
* 🔴 為什麼是 throw 不是回空字串:這支的呼叫端是文件站的建置。
|
||||
* 回空字串=建置成功、頁面少了整條桌面版版本歷史、**沒有任何人會發現**——
|
||||
* 那正是 D95 第二輪抓到的那個形狀(出貨線問錯檔案就整站安靜跳過)。
|
||||
* 壞掉要當場停,不要安靜地產出一個少一半的頁面。
|
||||
*/
|
||||
export function releasedSectionsFromFile(changelogPath = CHANGELOG_PATH) {
|
||||
if (!existsSync(changelogPath)) {
|
||||
throw new Error(`找不到 daemon 的版本說明檔:${changelogPath}(單一真相源=collector/CHANGELOG.md)`);
|
||||
}
|
||||
const r = releasedSections(readFileSync(changelogPath, 'utf8'));
|
||||
if (!r.versions.length) {
|
||||
throw new Error(
|
||||
`${changelogPath} 裡沒有任何**已發佈**的版本段(\`## vX.Y.Z(日期)\`)。\n` +
|
||||
' → 若只有「下一版(未發佈)」,先跑 `daemon-version.py --stamp` 戳成正式版號。');
|
||||
}
|
||||
return { ...r, path: changelogPath };
|
||||
}
|
||||
|
||||
/**
|
||||
* 從 changelog 取某一版的「一句話摘要」清單。
|
||||
* 規則:只認**頂層條目**(行首 `- `)的第一個粗體片段——那就是該條的標題。
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
/**
|
||||
* daemon-notes.test.mjs — `releasedSections()` 的演練(D95 第三輪)
|
||||
*
|
||||
* 這支存在的理由:`releasedSections()` 的產出**會直接變成使用者讀的那一頁**
|
||||
* (`rag.arcrun.dev/docs/help/changelog/`)。它多切一段、少切一段、或把給維護者看的
|
||||
* preamble 漏出去,都是使用者當場看得到的錯,而建置不會報任何錯。
|
||||
*
|
||||
* 跑法:node --test collector/cmd/arcrun-app/daemon-notes.test.mjs
|
||||
*/
|
||||
import { test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { releasedSections, releasedSectionsFromFile, CHANGELOG_PATH } from './daemon-notes.mjs';
|
||||
|
||||
const FIXTURE = [
|
||||
'# Arcrun 桌面版(daemon)版本說明',
|
||||
'',
|
||||
'> 給維護者看的說明,不該出現在網站上。',
|
||||
'',
|
||||
'## 怎麼出新版(不要手打版本號)',
|
||||
'',
|
||||
'在本檔最上面加一個二級標題:',
|
||||
'',
|
||||
' <二級標題> 下一版(未發佈)',
|
||||
'',
|
||||
'---',
|
||||
'',
|
||||
'## 下一版(未發佈)',
|
||||
'',
|
||||
'- 🔑 **還沒戳版號的東西**:不該出現在網站上。',
|
||||
'',
|
||||
'## v0.18.29(2026-08-16)',
|
||||
'',
|
||||
'**建議更新**',
|
||||
'',
|
||||
'- 🔑 **甲**:內文甲。',
|
||||
'',
|
||||
'### 小標題也要留著',
|
||||
'',
|
||||
'- 乙',
|
||||
'',
|
||||
'## v0.18.28(2026-08-16)',
|
||||
'',
|
||||
'- 丙',
|
||||
'',
|
||||
].join('\n');
|
||||
|
||||
test('只留已發佈段落:preamble 與「下一版(未發佈)」都不會被投影出去', () => {
|
||||
const { markdown, versions } = releasedSections(FIXTURE);
|
||||
assert.deepEqual(versions, ['v0.18.29', 'v0.18.28']);
|
||||
for (const forbidden of ['給維護者看的說明', '怎麼出新版', '<二級標題>', '下一版(未發佈)', '還沒戳版號']) {
|
||||
assert.ok(!markdown.includes(forbidden), `不該出現在使用者眼前:${forbidden}`);
|
||||
}
|
||||
assert.ok(markdown.startsWith('## v0.18.29(2026-08-16)'), '第一行就該是最新的已發佈版本');
|
||||
});
|
||||
|
||||
test('段落內文原樣保留,`###` 小標題不會被當成段落結束', () => {
|
||||
const { markdown } = releasedSections(FIXTURE);
|
||||
assert.ok(markdown.includes('### 小標題也要留著'));
|
||||
assert.ok(markdown.includes('- 乙'), '`###` 之後的內容仍屬於同一個版本段');
|
||||
assert.ok(markdown.includes('**建議更新**') && markdown.includes('- 丙'));
|
||||
});
|
||||
|
||||
test('一段都沒有就 throw——不准安靜回空字串(那會建出一頁少一半的東西)', () => {
|
||||
assert.throws(
|
||||
() => releasedSectionsFromFile('/nonexistent/CHANGELOG.md'),
|
||||
/找不到 daemon 的版本說明檔/);
|
||||
// 只有未發佈段落時同樣要停
|
||||
const onlyUnreleased = '# 標題\n\n## 下一版(未發佈)\n\n- 甲\n';
|
||||
assert.deepEqual(releasedSections(onlyUnreleased).versions, []);
|
||||
});
|
||||
|
||||
test('對真的 collector/CHANGELOG.md 跑一次:段數=檔案裡 `## vX.Y.Z` 的行數', () => {
|
||||
const raw = readFileSync(CHANGELOG_PATH, 'utf8');
|
||||
const expected = raw.split('\n').filter((l) => /^##\s+v\d+\.\d+\.\d+/.test(l)).length;
|
||||
const { versions, markdown } = releasedSectionsFromFile();
|
||||
assert.equal(versions.length, expected);
|
||||
assert.ok(expected > 0, '真檔裡至少要有一個已發佈版本');
|
||||
assert.ok(!markdown.includes('單一真相源'), '檔頭那段維護者說明不該被投影出去');
|
||||
});
|
||||
Reference in New Issue
Block a user