Skip to content

Commit 4e28130

Browse files
committed
Tooling: Add check for CHANGELOG commit-link integrity
- New `changelog-commit-links` check (nickname `changelog-links`) validates every `https://github.com/vdavid/cmdr/commit/<sha>` URL in `CHANGELOG.md` resolves to a real commit - Uses a single `git cat-file --batch-check` process — 616 SHAs resolved in ~55ms (down from ~1.8s with per-SHA subprocesses) - Also flags text/URL SHA mismatches in `[hash](url)` pairs, SHAs shorter than 6 chars, and SHAs longer than 40 chars - Registered for `AppOther` alongside `oxfmt` and `file-length`; wired into the `desktop-svelte`, `website`, and `api-server` CI jobs (each with `fetch-depth: 0` so historical SHAs resolve) - Tests cover happy path, bad URL SHA, text/URL mismatch, too-short SHA, no-links, and missing-`CHANGELOG.md` cases - Surfaced and fixed 8 bad links in the 0.12.0 and earlier sections: one 5-char SHA (`04359`), two prefixes ambiguous with trees (`0461e3`, `a61376`), and five typos (`9354806`, `3155609`, `634125`, `392819`, `254075a`) - Added a `### Non-app` bullet to the `[Unreleased]` section (link to be backfilled once this commit lands)
1 parent 9133afa commit 4e28130

6 files changed

Lines changed: 488 additions & 9 deletions

File tree

.github/workflows/ci.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,8 @@ jobs:
126126
steps:
127127
- name: Checkout code
128128
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
129+
with:
130+
fetch-depth: 0 # full history so changelog-commit-links can resolve historical SHAs
129131

130132
- name: Install mise
131133
uses: jdx/mise-action@1648a7812b9aeae629881980618f079932869151 # v4
@@ -155,6 +157,9 @@ jobs:
155157
- name: Check oxfmt
156158
run: ./scripts/check/check --check oxfmt --ci
157159

160+
- name: Check CHANGELOG commit links
161+
run: ./scripts/check/check --check changelog-commit-links --ci
162+
158163
- name: Run ESLint
159164
run: ./scripts/check/check --check desktop-svelte-eslint --ci
160165

@@ -237,6 +242,8 @@ jobs:
237242
steps:
238243
- name: Checkout code
239244
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
245+
with:
246+
fetch-depth: 0 # full history so changelog-commit-links can resolve historical SHAs
240247

241248
- name: Install mise
242249
uses: jdx/mise-action@1648a7812b9aeae629881980618f079932869151 # v4
@@ -262,6 +269,9 @@ jobs:
262269
- name: Check oxfmt
263270
run: ./scripts/check/check --check oxfmt --ci
264271

272+
- name: Check CHANGELOG commit links
273+
run: ./scripts/check/check --check changelog-commit-links --ci
274+
265275
- name: Run ESLint
266276
run: ./scripts/check/check --check website-eslint --ci
267277

@@ -307,6 +317,8 @@ jobs:
307317
steps:
308318
- name: Checkout code
309319
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
320+
with:
321+
fetch-depth: 0 # full history so changelog-commit-links can resolve historical SHAs
310322

311323
- name: Install mise
312324
uses: jdx/mise-action@1648a7812b9aeae629881980618f079932869151 # v4
@@ -332,6 +344,9 @@ jobs:
332344
- name: Check oxfmt
333345
run: ./scripts/check/check --check oxfmt --ci
334346

347+
- name: Check CHANGELOG commit links
348+
run: ./scripts/check/check --check changelog-commit-links --ci
349+
335350
- name: Run ESLint
336351
run: ./scripts/check/check --check api-server-eslint --ci
337352

CHANGELOG.md

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,14 @@ The format is based on [keep a changelog](https://keepachangelog.com/en/1.1.0/),
115115
[009b851e](https://github.com/vdavid/cmdr/commit/009b851e),
116116
[75f856e8](https://github.com/vdavid/cmdr/commit/75f856e8)).
117117

118+
### Non-app
119+
120+
- `changelog-commit-links` check validates every `https://github.com/vdavid/cmdr/commit/<sha>` URL in CHANGELOG.md
121+
resolves to a real commit, via a single `git cat-file --batch-check` process — catches typos, truncated SHAs, and
122+
prefixes ambiguous with trees before they land. Runs in the desktop-svelte, website, and api-server CI jobs (each does
123+
a full-depth checkout so historical SHAs resolve). Surfaced and fixed 8 bad links in the 0.12.0 and earlier sections
124+
along the way
125+
118126
## [0.12.0] - 2026-04-18
119127

120128
### Added
@@ -134,7 +142,7 @@ The format is based on [keep a changelog](https://keepachangelog.com/en/1.1.0/),
134142
SMB↔SMB copies flow through memory without temp files, and large local↔NAS copies stay bounded to ~1 MiB peak RAM
135143
instead of buffering the whole file ([ac71bd](https://github.com/vdavid/cmdr/commit/ac71bd),
136144
[a82709](https://github.com/vdavid/cmdr/commit/a82709), [35120d](https://github.com/vdavid/cmdr/commit/35120d),
137-
[04359](https://github.com/vdavid/cmdr/commit/04359))
145+
[043597f](https://github.com/vdavid/cmdr/commit/043597f))
138146
- SMB mount disambiguation — two shares with the same name from different servers now get unique mount points (`public`,
139147
`public-1`, …) via `kNetFSForceNewSessionKey`. Volume switcher shows `{share} on {server}` so it's clear which is
140148
which ([76671b](https://github.com/vdavid/cmdr/commit/76671b))
@@ -234,12 +242,12 @@ The format is based on [keep a changelog](https://keepachangelog.com/en/1.1.0/),
234242
test or an allowlist entry ([33300a4](https://github.com/vdavid/cmdr/commit/33300a4),
235243
[d56c1df](https://github.com/vdavid/cmdr/commit/d56c1df), [398bf7a](https://github.com/vdavid/cmdr/commit/398bf7a))
236244
- Switch from Lucide components to UnoCSS pure-CSS icons — zero JS runtime, recolor via `currentColor` + CSS vars,
237-
`mask-image` rendering ([9354806](https://github.com/vdavid/cmdr/commit/9354806))
245+
`mask-image` rendering ([93548fa](https://github.com/vdavid/cmdr/commit/93548fa))
238246
- File-length check + allowlist — tool flags files growing past a tracked size, 31 baseline entries. Split 20+ long
239247
files into sub-800-line modules (`volume_copy.rs`, `scan.rs`, `smb.rs`, `integration_test.rs`, `AiSection.svelte`,
240248
`+page.svelte`, `DualPaneExplorer.svelte`, and more) — pure mechanical splits, no logic changes
241249
([7514cb4](https://github.com/vdavid/cmdr/commit/7514cb4), [2939bfe](https://github.com/vdavid/cmdr/commit/2939bfe),
242-
[4514a83](https://github.com/vdavid/cmdr/commit/4514a83), [3155609](https://github.com/vdavid/cmdr/commit/3155609))
250+
[4514a83](https://github.com/vdavid/cmdr/commit/4514a83), [315609a](https://github.com/vdavid/cmdr/commit/315609a))
243251
- `OperationEventSink` + `ListingEventSink` traits decouple copy/move/listing pipelines from `tauri::AppHandle`
244252
enables unit tests without a Tauri runtime; `CollectorEventSink` stores events for assertions
245253
([35fea46](https://github.com/vdavid/cmdr/commit/35fea46), [0a6ae61](https://github.com/vdavid/cmdr/commit/0a6ae61))
@@ -379,7 +387,7 @@ The format is based on [keep a changelog](https://keepachangelog.com/en/1.1.0/),
379387
- MCP: `cmdr://settings` resource and `set_setting` tool — inspect and change all settings without opening the Settings
380388
window ([c71115](https://github.com/vdavid/cmdr/commit/c71115))
381389
- MCP: `move_cursor` now awaits frontend confirmation, fixing race where `copy` fires before cursor has moved
382-
([634125](https://github.com/vdavid/cmdr/commit/634125))
390+
([6341c25](https://github.com/vdavid/cmdr/commit/6341c25))
383391

384392
### Fixed
385393

@@ -395,7 +403,7 @@ The format is based on [keep a changelog](https://keepachangelog.com/en/1.1.0/),
395403
- MTP: fix volumes missing from copy/move dialog, fix destination volume dropdown not updating on change
396404
([cd6603](https://github.com/vdavid/cmdr/commit/cd6603))
397405
- MTP: fix event loop lock contention — clone `MtpDevice` for event polling instead of holding mutex during
398-
`next_event()`, unblocking copy/move/scan operations ([0461e3](https://github.com/vdavid/cmdr/commit/0461e3),
406+
`next_event()`, unblocking copy/move/scan operations ([0461e33](https://github.com/vdavid/cmdr/commit/0461e33),
399407
[547a41](https://github.com/vdavid/cmdr/commit/547a41))
400408
- MTP: fix scan preview showing 0/0/0 in confirmation dialog, reduce USB round-trips for conflict checks
401409
([4e1efa](https://github.com/vdavid/cmdr/commit/4e1efa))
@@ -499,7 +507,7 @@ The format is based on [keep a changelog](https://keepachangelog.com/en/1.1.0/),
499507
- MTP: show loading progress when opening large folders ([77ebaa](https://github.com/vdavid/cmdr/commit/77ebaa))
500508
- Add missing focus indicators on search and command palette inputs
501509
([179221](https://github.com/vdavid/cmdr/commit/179221))
502-
- Selection summary now includes directory sizes ([392819](https://github.com/vdavid/cmdr/commit/392819))
510+
- Selection summary now includes directory sizes ([3928c1c](https://github.com/vdavid/cmdr/commit/3928c1c))
503511
- MCP: show directory sizes in state resource ([9cb775](https://github.com/vdavid/cmdr/commit/9cb775))
504512

505513
### Fixed
@@ -520,7 +528,7 @@ The format is based on [keep a changelog](https://keepachangelog.com/en/1.1.0/),
520528
- Fix stale dir sizes on rename — writer now emits notifications after both delete+insert commit
521529
([10213d](https://github.com/vdavid/cmdr/commit/10213d))
522530
- Fix indexing won't start on fresh DB — `scanning` flag moved to correct path
523-
([a61376](https://github.com/vdavid/cmdr/commit/a61376))
531+
([a61376d](https://github.com/vdavid/cmdr/commit/a61376d))
524532
- Fix "Scanning..." stuck after replay — clear scanning in replay-complete handler
525533
([4a44d7](https://github.com/vdavid/cmdr/commit/4a44d7), [fb796e](https://github.com/vdavid/cmdr/commit/fb796e))
526534
- Fix verifier + replay transaction conflict — use named savepoints instead of nested transactions
@@ -1017,7 +1025,7 @@ The format is based on [keep a changelog](https://keepachangelog.com/en/1.1.0/),
10171025
- Add type drift detection between Rust and Svelte types ([b3ae1c3](https://github.com/vdavid/cmdr/commit/b3ae1c3))
10181026
- Add jscpd for Rust code duplication detection, CSS health checks, Go checks
10191027
([67e6c15](https://github.com/vdavid/cmdr/commit/67e6c15), [d177eb3](https://github.com/vdavid/cmdr/commit/d177eb3),
1020-
[254075a](https://github.com/vdavid/cmdr/commit/254075a))
1028+
[2540752](https://github.com/vdavid/cmdr/commit/2540752))
10211029
- Add Claude hooks for pre-session context and post-edit autoformat
10221030
([3d59dde](https://github.com/vdavid/cmdr/commit/3d59dde), [122182d](https://github.com/vdavid/cmdr/commit/122182d))
10231031
- Add LogTape logging for Svelte and debug pane for dev mode ([affa548](https://github.com/vdavid/cmdr/commit/affa548),

scripts/check/CLAUDE.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ go run ./scripts/check --only-freestyle
9797
| `checks/website-*.go`, `checks/api-server-*.go`, `checks/scripts-go-*.go` | One file per check |
9898
| `checks/file-length.go` | Informational file-length scanner (warn-only, never fails). Supports an allowlist. |
9999
| `checks/file-length-allowlist.json` | Allowlist for file-length check: `{ "files": { "path": lineCount } }`. Files at or below their allowlisted count are suppressed. |
100+
| `checks/changelog-commit-links.go` | Validates every `https://github.com/vdavid/cmdr/commit/<sha>` URL in `CHANGELOG.md` resolves, via a single `git cat-file --batch-check` process. |
100101

101102
## Key patterns
102103

@@ -193,7 +194,7 @@ before tests.
193194
| Website | Docker | docker-build |
194195
| API server | TS | oxfmt, eslint, typecheck, tests |
195196
| Scripts | Go | gofmt, go-vet, staticcheck, ineffassign, misspell, gocyclo, nilaway, deadcode, go-tests |
196-
| Other | Metrics | file-length (warn-only) |
197+
| Other | Metrics | file-length (warn-only), CLAUDE.md-staleness (warn-only), changelog-commit-links |
197198

198199
## Output format
199200

0 commit comments

Comments
 (0)