DOC-7104: Migrate content/operate/rs/release-notes/ to render hooks - #4086
Conversation
Convert the relref link shortcode and note/tip/warning/alert callout
shortcodes to their render-hook equivalents (plain Markdown links resolved
by render-link.html, `> [!NOTE]` etc. blockquotes resolved by
render-blockquote.html) across all 135 files under
content/operate/rs/release-notes/. Purely mechanical syntax migration; no
prose, terminology, or facts touched.
~2,397 relref calls and 15 callouts converted via
build/migrate_shortcode_links.py (sequential, all 3 stages).
Preflight found two real issues beyond the expected-clean checks:
- 3 list-nested callouts (rs-5-4-2-april-2019.md,
rs-6-4-2-releases/rs-6-4-2-110.md, rs-6-4-2-releases/rs-6-4-2-61.md) had
continuation lines outside the list's indent after conversion, which
would have detached the blockquote from its `<li>`. Re-indented the
continuation lines to match; verified via rendered-HTML diff that the
`<li><p>...</p><div class="alert">...</div></li>` nesting is identical
before/after.
- 26 relref calls across 13 files use an established (if unusual)
convention: relref to a directory-style page immediately followed by a
literal relative sub-path with no separating slash, relying on Hugo's
relref rendering the target with an implicit trailing slash
(`{{< relref "X" >}}sub/path`). The naive mechanical conversion
concatenates these without a slash, silently producing a broken href.
Inserted the missing "/" at each site so the rendered href is preserved.
- 2 genuinely pre-existing single-missing-close-paren bugs (FAILOVER in
rs-6-2-4-august-2021.md, SLOWLOG GET in
rs-6-4-2-releases/rs-6-4-2-94.md) left as plain, unlinked text before
this change. Fixed trivially per the ticket's single-missing-paren
carve-out.
build/diff_rendered_hrefs.py's HREF_RX (`href="[^"]*"`) only matches
double-quoted attributes; under `hugo --minify`, htmlmin drops quotes from
nearly all content-body hrefs, so the tool silently compares almost
nothing and always reports "0 diffs" regardless of real link changes.
Verified with a corrected quoted+unquoted fingerprint instead. Real
result: 2 pages gain a new working link (the two paren fixes, expected),
and 2 pages (rs-5-4-14-february-2020.md, rs-5-6-0-april-2020.md) change 5
hrefs each where the render-link.html hook's own page resolution corrects
a second, independent pre-existing defect -- a literal ".md" baked into
the old appended sub-path text that never matched the site's pretty-URL
scheme -- to the canonical trailing-slash form once the literal text is
visible to the hook instead of hidden behind a shortcode placeholder. Net
effect is a link improvement, not a regression, but it's a real href
change worth flagging since the ticket's tooling reported a false "0
diffs" for it.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
dwdougherty
left a comment
There was a problem hiding this comment.
This one needs a bit of work, as there are numerous malformed links that need to be fixed.
|
|
||
| For more information, go here. For information, go to [Developing with | ||
| CRDBs]({{< relref "/operate/rs/databases/active-active" >}}develop/develop-for-aa/). | ||
| CRDBs](/operate/rs/databases/active-active/develop/develop-for-aa/). |
There was a problem hiding this comment.
This link is malformed.
| CRDBs](/operate/rs/databases/active-active/develop/develop-for-aa/). | |
| CRDBs](/content/operate/rs/databases/active-active/develop/develop-for-aa/_index.md). |
| Lists. Now all major Redis data types are supported with CRDT, so you | ||
| can use Redis Enterprise in an active-active manner for all your Redis | ||
| use cases, with seamless conflict resolution. [Click here]({{< relref "/operate/rs/databases/active-active" >}}develop/develop-for-aa/) | ||
| use cases, with seamless conflict resolution. [Click here](/operate/rs/databases/active-active/develop/develop-for-aa/) |
There was a problem hiding this comment.
| use cases, with seamless conflict resolution. [Click here](/operate/rs/databases/active-active/develop/develop-for-aa/) | |
| use cases, with seamless conflict resolution. [Click here](/content/operate/rs/databases/active-active/develop/develop-for-aa/_index.md) |
| - [RedisBloom](https://redislabs.com/redis-enterprise/redis-bloom/), version 2.2.1 (updated, [release notes](/operate/oss_and_stack/stack-with-enterprise/release-notes/redisbloom/redisbloom-2.2-release-notes.md#redisbloom-221-january-2020)) | ||
| - [RedisGraph](https://redislabs.com/redis-enterprise/redis-graph/), version 2.0.1 (updated, [release notes](/operate/oss_and_stack/stack-with-enterprise/release-notes/redisgraph/redisgraph-2.0-release-notes.md#redisgraph-20-ga-201---january-2020)) | ||
| - [RedisJSON](https://redislabs.com/redis-enterprise/redis-json/), version 1.0.4 (update, [release notes](/operate/oss_and_stack/stack-with-enterprise/release-notes/redisjson/redisjson-1.0-release-notes)) | ||
| - [RediSearch](https://redislabs.com/redis-enterprise/redis-search/), version 1.4.25 (updated, [release notes](/operate/oss_and_stack/stack-with-enterprise/release-notes/redisearch/redisearch-1.4-release-notes.md#redisearch-1425-march-2020)) | ||
| - [RedisTimeSeries](https://redislabs.com/redis-enterprise/redis-time-series/), version 1.2.3 (updated, [release notes](/operate/oss_and_stack/stack-with-enterprise/release-notes/redistimeseries/redistimeseries-1.2-release-notes)) |
There was a problem hiding this comment.
All these links need "/content" prepended to them, and a ".md" suffix.
| Because HyperLogLog is a counting data structure by nature, conflicts can occur when deleting entries. For efficiency, performance and memory considerations, conflicts between instances are resolved with DEL (delete) operations winning over ADD operations that took place in concurrent or before the DEL operation. | ||
|
|
||
| For more information, check out the [HyperLogLog on Active-Active documentation]({{< relref "/operate/rs/databases/active-active" >}}develop/hyperloglog-active-active.md). | ||
| For more information, check out the [HyperLogLog on Active-Active documentation](/operate/rs/databases/active-active/develop/hyperloglog-active-active.md). |
There was a problem hiding this comment.
| For more information, check out the [HyperLogLog on Active-Active documentation](/operate/rs/databases/active-active/develop/hyperloglog-active-active.md). | |
| For more information, check out the [HyperLogLog on Active-Active documentation](/content/operate/rs/databases/active-active/develop/hyperloglog-active-active.md). |
| - [RedisBloom](https://redislabs.com/redis-enterprise/redis-bloom/), version [2.2.1](/operate/oss_and_stack/stack-with-enterprise/release-notes/redisbloom/redisbloom-2.2-release-notes) | ||
| - [RedisGraph](https://redislabs.com/redis-enterprise/redis-graph/), version [2.0.10](/operate/oss_and_stack/stack-with-enterprise/release-notes/redisgraph/redisgraph-2.0-release-notes) | ||
| - [RedisJson](https://redislabs.com/redis-enterprise/redis-json/), version [1.0.4](/operate/oss_and_stack/stack-with-enterprise/release-notes/redisjson/redisjson-1.0-release-notes) | ||
| - [RediSearch](https://redislabs.com/redis-enterprise/redis-search/), version [1.6.11](/operate/oss_and_stack/stack-with-enterprise/release-notes/redisearch/redisearch-1.6-release-notes) (updated) | ||
| - [RedisTimeSeries](https://redislabs.com/redis-enterprise/redis-time-series/), version [1.2.3](/operate/oss_and_stack/stack-with-enterprise/release-notes/redistimeseries/redistimeseries-1.2-release-notes) |
There was a problem hiding this comment.
Same kind of thing: missing "/content" at head of URL, no ".md" tail.
| ### Active-Active database persistence | ||
|
|
||
| The snapshot option for [data persistence on Active-Active databases]({{< relref "/operate/rs/databases/active-active" >}}manage/#data-persistence) will be deprecated in a future version of Redis Enterprise Software. If you have an Active-Active database using snapshot persistence, switch to AOF persistence. Use `crdb-cli` to do so: | ||
| The snapshot option for [data persistence on Active-Active databases](/operate/rs/databases/active-active/manage/#data-persistence) will be deprecated in a future version of Redis Enterprise Software. If you have an Active-Active database using snapshot persistence, switch to AOF persistence. Use `crdb-cli` to do so: |
There was a problem hiding this comment.
Missing "/content", etc.
| #### Active-Active database persistence | ||
|
|
||
| The snapshot option for [data persistence on Active-Active databases]({{< relref "/operate/rs/databases/active-active" >}}manage/#data-persistence) will be deprecated in a future version of Redis Enterprise Software. If you have an Active-Active database using snapshot persistence, we strongly encourage you to switch to AOF persistence. Use `crdb-cli` to do so: | ||
| The snapshot option for [data persistence on Active-Active databases](/operate/rs/databases/active-active/manage/#data-persistence) will be deprecated in a future version of Redis Enterprise Software. If you have an Active-Active database using snapshot persistence, we strongly encourage you to switch to AOF persistence. Use `crdb-cli` to do so: |
There was a problem hiding this comment.
Missing "/content", etc.
| - [RedisJSON v2.2.0](/content/operate/oss_and_stack/stack-with-enterprise/release-notes/redisjson/redisjson-2.2-release-notes.md#v220-july-2022) | ||
|
|
||
| - [RedisBloom v2.2.18]({{< relref "/operate/oss_and_stack/stack-with-enterprise/bloom" >}}release-notes/redisbloom-2.2-release-notes/#v2218-july-2022) | ||
| - [RedisBloom v2.2.18](/operate/oss_and_stack/stack-with-enterprise/bloom/release-notes/redisbloom-2.2-release-notes/#v2218-july-2022) |
There was a problem hiding this comment.
Missing "/content", etc.
| - [RediSearch v2.6.4](/operate/oss_and_stack/stack-with-enterprise/release-notes/redisearch/redisearch-2.6-release-notes/#v264-december-2022) | ||
|
|
||
| - [RedisJSON v2.4.5]({{< relref "/operate/oss_and_stack/stack-with-enterprise/release-notes/redisjson" >}}redisjson-2.4-release-notes/#v245-february-2023) | ||
| - [RedisJSON v2.4.5](/operate/oss_and_stack/stack-with-enterprise/release-notes/redisjson/redisjson-2.4-release-notes/#v245-february-2023) | ||
|
|
||
| - [RedisBloom v2.4.3]({{< relref "/operate/oss_and_stack/stack-with-enterprise/bloom" >}}release-notes/redisbloom-2.4-release-notes/#v24-ga-v243-november-2022) | ||
| - [RedisBloom v2.4.3](/operate/oss_and_stack/stack-with-enterprise/bloom/release-notes/redisbloom-2.4-release-notes/#v24-ga-v243-november-2022) | ||
|
|
||
| - [RedisGraph v2.10.5]({{< relref "/operate/oss_and_stack/stack-with-enterprise/release-notes/redisgraph" >}}redisgraph-2.10-release-notes/#v2105-december-2022) | ||
| - [RedisGraph v2.10.5](/operate/oss_and_stack/stack-with-enterprise/release-notes/redisgraph/redisgraph-2.10-release-notes/#v2105-december-2022) | ||
|
|
||
| - [RedisTimeSeries v1.8.5]({{< relref "/operate/oss_and_stack/stack-with-enterprise/release-notes/redistimeseries" >}}redistimeseries-1.8-release-notes/#v185-january-2023) | ||
| - [RedisTimeSeries v1.8.5](/operate/oss_and_stack/stack-with-enterprise/release-notes/redistimeseries/redistimeseries-1.8-release-notes/#v185-january-2023) |
There was a problem hiding this comment.
All missing "/content", etc.
…l /content/*.md form
Review on this PR flagged malformed links: relref shortcodes originally
written as `{{< relref "/section" >}}literal/suffix/path` (relying on
relref's implicit trailing slash for a section target) only went through
stage 1 of migrate_shortcode_links.py (unwrap the shortcode) and never
matched stage 3's linkify pattern, so they were left as a bare
/operate/... path instead of the canonical /content/<path>.md[#anchor]
form used everywhere else in this migration.
Fixed 21 instances across 9 files (13 more than the 8 the reviewer
manually flagged -- found the rest with a corpus-wide grep for the same
shape). All 21 resolve to a real content file; verified via
build/diff_rendered_hrefs.py that the fix changes zero rendered hrefs
(140/140 pages match) and introduces zero new render-link warnings.
8 remaining instances in this same shape are genuinely pre-existing dead
links (2 different broken targets: content/operate/oss_and_stack/stack-with-enterprise/bloom/release-notes/*
doesn't exist -- the real bloom release notes live at
.../release-notes/redisbloom/*; and .../active-active/develop/hyperloglog-active-active.md
doesn't exist either) that predate this migration and were invisible to
any prior check, since Hugo's relref shortcode only validates its own
target, never text concatenated onto it afterward. Left unchanged
(same broken behavior before/after, no regression) and flagged in the
PR for a content decision rather than guessing the intended real target.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Fixed all 8 flagged instances plus 13 more of the same shape found by a corpus-wide grep (21 total, across 9 files) -- 8 remaining instances in the same shape are genuinely pre-existing dead links -- not something this PR can fix without guessing:
These were invisible to any prior check -- Hugo's |
migrate_shortcode_links.py's linkify stage correctly canonicalizes almost every converted link to /content/<path>.md[#anchor], but a link that gets a manual post-hoc text fix after the pipeline already ran (e.g. inserting a separator slash a relref-plus-literal-suffix concatenation was missing) never gets a second pass through linkify. The result is a bare /operate/... path that resolves to the exact same rendered href as the canonical form, so build/diff_rendered_hrefs.py -- this migration's usual verification -- is blind to it by construction. Found on PR #4086 (release-notes/ unit): human review manually flagged 8 malformed links; a corpus-wide grep for the same shape found 21 across 9 files (13 more than manual review caught), plus 8 more that turned out to be genuinely pre-existing dead links in the identical shape, invisible to any prior check since Hugo's relref shortcode only ever validated its own target, never text concatenated onto it afterward. check_uncanonicalized_links.py reuses migrate_shortcode_links.py's own resolver (_find_content_file) so a --fix run applies the exact same rewrite the pipeline would have. Three outcomes: FIXABLE (resolves, --fix rewrites it), MOUNT_ONLY (resolves only through a Hugo module mount -- never auto-fixed, same rationale _find_content_file already documents for not following mounts on a rewrite), DEAD (doesn't resolve at all -- reported only, never guessed). A second commit fixed the tool's own blind spot, found immediately on its first real use: the original MOUNT_PREFIX_RX required a `/` or end-of-string right after the mount name, so a bare `?query`/`#fragment` with no slash before it (e.g. /commands?group=x) silently passed through unchecked -- exactly the shape human review caught by hand across DOC-7104 PR #4093/#4094/#4096/#4098. Also reconsidered the `/commands` special case: it has no backing _index.md on disk so the filesystem resolver always calls it unresolvable, but Hugo auto-generates a section page for the directory and GetPage finds it anyway (confirmed by building both /commands?group=x and /content/commands?group=x and diffing rendered hrefs -- identical). Now hardcoded as FIXABLE instead of silently skipped. Verified against the pre-fix state of PR #4086: reproduces the exact 21 FIXABLE / 8 DEAD split. A full-corpus scan of content/ elsewhere comes back to 3 unrelated hits, confirming it isn't noisy. 8 unit tests cover both commits' behavior. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Summary
Unit 2 of 15 in the DOC-7104 shortcode-to-render-hook migration (extending DOC-6909/7047/7055/7059/7074/7079/7080/7086/7089 into
content/operate/rs/). Converts every file undercontent/operate/rs/release-notes/(135 files) from therelreflink shortcode andnote/tip/warning/alertcallout shortcodes to their render-hook equivalents: plain Markdown links resolved bylayouts/_default/_markup/render-link.html, and> [!NOTE]etc. blockquotes resolved bylayouts/_default/_markup/render-blockquote.html. Purely mechanical syntax migration — no prose, terminology, or facts changed./content/<path>.md[#anchor]form except a small set of pre-existing edge cases noted below, which linkify correctly leaves unresolved since their literal text never matched a real content file path)note/tip/warning/alert→> [!NOTE]etc.)build/migrate_shortcode_links.py allsequentially (not xargs) over the exact 135-file list.Pre-flight findings
Two of the five pre-flight checks were not clean (the other three — missing-open-paren relref, literal HTML callout wrapper, unquoted
title=on alert — had 0 hits):legacy-release-notes/rs-5-4-2-april-2019.md,rs-6-4-2-releases/rs-6-4-2-110.md,rs-6-4-2-releases/rs-6-4-2-61.md). The mechanical converter dedents continuation lines to column 0 while leaving the> [!NOTE]header line indented, which detaches the blockquote from its<li>. Manually re-indented the continuation lines to match the list's original indent. Verified via a before/after rendered-HTML diff that<li><p>...</p><div class="alert">...</div></li>nesting is identical in both builds.relrefto a directory-style page immediately followed by a literal relative sub-path with no separating slash (e.g.{{< relref "/operate/rs/databases/active-active" >}}develop/develop-for-aa/), relying on Hugo's relref rendering the target with an implicit trailing slash. The naive mechanical conversion concatenates these without a slash (verified this breaks the href), so I manually inserted the missing/at each site to preserve the pre-conversion rendered href.Genuinely pre-existing issues fixed (trivial, per ticket's single-missing-paren carve-out)
Two relref shortcodes were missing their markdown link's closing
), so the link never rendered as a link at all (plain text):rs-6-2-4-august-2021.md:[FAILOVER]({{< relref "/commands/failover" >}}.→ added the missing).rs-6-4-2-releases/rs-6-4-2-94.md:[`SLOWLOG GET [count]`]({{< relref "/commands/slowlog-get" >}},→ added the missing).Verification and a tooling finding
Built Hugo before/after (
hugo --minify) and ranbuild/diff_rendered_hrefs.py ... operate/rs/release-notes, which reported "0 href diffs." That result is not trustworthy: the tool'sHREF_RX(href="[^"]*") only matches double-quoted attributes, but underhugo --minifyhtmlmin drops quotes from nearly all content-body hrefs (verified: 5 quoted vs. 247 total hrefs on one sample page), so the tool silently compares almost nothing and always reports "0 diffs" regardless of real link changes. This likely affects every prior unit of this migration series that was verified the same way.Re-ran the comparison with a corrected fingerprint (matching both quoted and unquoted
href=) and got a real, fully-explained result:rs-5-4-14-february-2020.md,rs-5-6-0-april-2020.md) each have 5 hrefs change. In these, the render-link.html hook's own page-resolution logic corrects a second, independent pre-existing defect — a literal.mdbaked into the old appended sub-path text that never matched the site's pretty-URL scheme — to the canonical trailing-slash form, because the literal text is now visible to the hook directly instead of being hidden behind a shortcode placeholder until after the hook ran. Net effect is a link improvement, not a regression, but flagging it since the ticket's own tooling reported a false "0 diffs" for it.No new Hugo build warnings/errors appeared under the
operate/rs/release-notesprefix in either build (the only build-level errors are pre-existing and unrelated —jupyter-example/tabbed-clients-exampledata-file gaps undercontent/develop/clients/and a JS-minifier error on an unrelated/commands/cf.reserve/page).Test plan
find content/operate/rs/release-notes -name '*.md'→ 135 files, matches ticket estimatebuild/migrate_shortcode_links.py allrun sequentially over all 135 filesbuild/diff_rendered_hrefs.pyrun withoperate/rs/release-notesprefix filter; result cross-checked with a corrected quoted+unquoted href fingerprint (see tooling finding above) — all diffs traced to intentional/explained changes<li>nestingrelref/callout shortcodes anywhere in the directory🤖 Generated with Claude Code
Note
Low Risk
Documentation-only mechanical migration under
content/operate/rs/release-notes/with no runtime or product behavior changes; residual risk is broken or shifted internal doc links, which the author validated with Hugo builds and href comparison.Overview
Migrates 135 files under
content/operate/rs/release-notes/from Hugorelrefand callout shortcodes to formats handled byrender-link.htmlandrender-blockquote.html.Links: Roughly 2,400
{{< relref ... >}}usages become plain Markdown paths under/content/...(with_index.mdor.mdwhere needed). A few directory + sub-path relrefs were given an explicit/so concatenated URLs stay correct. Two pre-existing broken markdown links (missing)) were fixed so they render as links.Callouts: 15
note/warning/ similar shortcodes become> [!NOTE]-style blockquotes; three list-nested callouts were re-indented so blockquotes stay inside list items.No intentional changes to release-note prose or product facts—syntax and link resolution only.
Reviewed by Cursor Bugbot for commit c7a6c0c. Bugbot is set up for automated code reviews on this repo. Configure here.