Skip to content

Updated blog structure#895

Open
n-boshnakov wants to merge 3 commits intogardener:masterfrom
n-boshnakov:n-boshnakov/updated-blog-structure
Open

Updated blog structure#895
n-boshnakov wants to merge 3 commits intogardener:masterfrom
n-boshnakov:n-boshnakov/updated-blog-structure

Conversation

@n-boshnakov
Copy link
Contributor

@n-boshnakov n-boshnakov commented Mar 11, 2026

How to categorize this PR?

/kind enhancement
/kind cleanup

What this PR does / why we need it:
This PR updates the blogs visualization. Major changes:

  • Added a tagging system to the blog posts (suggestion received via QRC, in addition to Apeiro requirements)
  • Added tags to existing blog posts
  • Added author name + image visualization
  • Added a search bar to display blogs with a specific tag/s
  • Added the same visualizations (tags + author) to each individual blog post

Which issue(s) this PR fixes:
Fixes #882

Special notes for your reviewer:
View of changes:

  • Main Blogs section
image
  • Individual blogs
Screenshot 2026-03-11 150711

Summary by CodeRabbit

  • New Features

    • Author attribution (names + optional avatars) and preview excerpts shown on blog posts.
    • Tags surfaced on posts and in listings; many posts received updated tags for better discovery.
    • Client-side tag filtering on the blog index with search, tag suggestions, toggleable tag buttons, Clear action and no-results messaging.
    • Blog index now rendered dynamically for interactive filtering.
  • Documentation

    • Added a blog tags guide describing supported tag categories and formats.

- added a tagging system to the blog posts in order to satisfy Apeiro requirement
- added tags to existing blog posts
- improved the view of the blogs
- added author name + picture for each post
- converted Hugo shortcode syntax inside Markdown to the Vitepress component format in order to fix build issues
@n-boshnakov n-boshnakov requested a review from a team as a code owner March 11, 2026 13:48
@netlify
Copy link

netlify bot commented Mar 11, 2026

Deploy Preview for gardener-docs ready!

Name Link
🔨 Latest commit 2258e71
🔍 Latest deploy log https://app.netlify.com/projects/gardener-docs/deploys/69b18d7a41546b00087f7b6f
😎 Deploy Preview https://deploy-preview-895--gardener-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
Lighthouse
Lighthouse
1 paths audited
Performance: 64 (🔴 down 2 from production)
Accessibility: 97 (no change from production)
Best Practices: 100 (no change from production)
SEO: 97 (🔴 down 1 from production)
PWA: 90 (no change from production)
View the detailed breakdown and full score reports

To edit notification comments on pull requests, go to your Netlify project configuration.

@gardener-prow
Copy link

gardener-prow bot commented Mar 11, 2026

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign klocke-io for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@gardener-prow gardener-prow bot added do-not-merge/needs-kind Indicates a PR lacks a `kind/foo` label and requires one. cla: yes Indicates the PR's author has signed the cla-assistant.io CLA. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. labels Mar 11, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 11, 2026

📝 Walkthrough

Walkthrough

Refactors the VitePress blog data pipeline to surface authors, tags, previews, and robust date handling; adds client-side tag filtering in the blog index; introduces a BlogPostMeta component; adds an automated tag-application script and applies tags across many blog posts.

Changes

Cohort / File(s) Summary
Blog data & helpers
.vitepress/data/blog.data.ts
Reworked blog loader: added Author interface, updated Post shape (authors, tags, preview), new date parsing/formatting helpers, preview extraction, author/tag normalization, and new render: true loader option.
Theme components & wiring
.vitepress/theme/components/BlogIndex.vue, .vitepress/theme/components/BlogPostMeta.vue, .vitepress/theme/index.ts
Added client-side tag filtering (query, selectedTags, filteredPosts), per-post tag toggles, tag UI; new BlogPostMeta component renders date/authors/tags; integrated BlogPostMeta into theme doc-before layout.
Automation & tooling
hack/apply-blog-tags.mjs, hack/preview.sh
New tag-inference script to infer/merge tags into post frontmatter (dry-run supported); minor docker port quoting fix in preview script.
Content metadata
website/blog/**/*.md (50+ files)
Added/updated front-matter tags (and some authors) across many posts; minor content/formatting edits in several posts.
Index & docs
website/blog/index.md, website/documentation/contribute/documentation/blog-tags.md, website/documentation/contribute/documentation/style-guide/_index.md, website/documentation/resources/videos/livecheck-readiness.md
Replaced static blog index content with BlogIndex component; added Tag taxonomy and blog metadata guidance; minor newline/format fixes.

Sequence Diagram(s)

sequenceDiagram
  participant Reader
  participant Browser
  participant Theme as "VitePress Theme\n(BlogIndex / BlogPostMeta)"
  participant Loader as ".vitepress/data/blog.data.ts"
  participant FS as "Markdown Files\n(website/blog/*.md)"

  Reader->>Browser: Open /blog
  Browser->>Theme: render BlogIndex
  Theme->>Loader: request posts (render: true)
  Loader->>FS: read blog markdown files & frontmatter
  FS-->>Loader: raw frontmatter + content
  Loader->>Loader: normalize authors, tags, preview, parse/format dates
  Loader-->>Theme: Post[] (title,url,authors,tags,preview,date)
  Theme-->>Browser: render filtered posts UI
  Browser->>Theme: user toggles tag / types tag query
  Theme->>Theme: compute filteredPosts (selectedTags, tagQuery)
  Theme-->>Browser: update displayed posts
  Browser->>Theme: open post
  Theme->>Loader: (post metadata already available) supply metadata
  Theme->>Browser: render BlogPostMeta (date, authors, tags)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related issues

Possibly related PRs

Suggested labels

kind/enhancement, kind/cleanup, needs/review

Suggested reviewers

  • BoHristova
  • dnaeon

Poem

🐰 I hopped through frontmatter, tags in tow,

authors gathered where previews grow,
Filters dance as readers seek,
Dates now tidy, metadata sleek —
A tiny rabbit cheers the blog's new show!

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'Updated blog structure' is vague and generic, using non-descriptive language that does not convey meaningful information about the significant changes in this PR. Revise the title to be more specific and descriptive, such as 'Add blog tagging system, author metadata, and filtering UI' or 'Implement blog post tags, author visualization, and search filtering'.
✅ Passed checks (3 passed)
Check name Status Explanation
Description check ✅ Passed The PR description is mostly complete, covering the main changes (tagging system, author visualization, search bar) and linking to the relevant issue, though it could be more detailed about technical implementation specifics.
Linked Issues check ✅ Passed The PR implements all major requirements from issue #882: added tag system for blog filtering [#882], author/avatar visualization [#882], and improved blog layout with search functionality [#882].
Out of Scope Changes check ✅ Passed All changes are directly scoped to the requirements: blog post data structure updates, tagging system implementation, UI components for filtering and metadata display, and documentation of the tagging system.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@n-boshnakov n-boshnakov changed the title Updated blog structure: - added a tagging system to the blog posts in order to satisfy Apeiro requirement - added tags to existing blog posts - improved the view of the blogs - added author name + picture for each post - converted Hugo shortcode syntax inside Markdown to the Vitepress component format in order to fix build issues Updated blog structure Mar 11, 2026
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 17

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
website/blog/2018/06/06.11-shared-storage-with-s3-backend.md (1)

20-20: ⚠️ Potential issue | 🟡 Minor

Consider a more appropriate transition word.

The word "However" typically signals a contrast or contradiction, but this sentence introduces an additional use case rather than contrasting with the previous content. Consider using "Additionally", "Furthermore", or "For example" instead for better clarity.

✍️ Suggested improvement
-However, it can be used to import and parse large amounts of data into a database.
+Additionally, it can be used to import and parse large amounts of data into a database.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@website/blog/2018/06/06.11-shared-storage-with-s3-backend.md` at line 20,
Replace the transitional adverb "However" at the start of the sentence "However,
it can be used to import and parse large amounts of data into a database." with
a more appropriate connector such as "Additionally," or "Furthermore," (or "For
example," if you intend to illustrate a use case) so the sentence reads e.g.
"Additionally, it can be used to import and parse large amounts of data into a
database." This change improves cohesion without altering the sentence content.
website/blog/2018/12/12.25-gardener-cookies.md (1)

17-17: ⚠️ Potential issue | 🔴 Critical

Fix CSS syntax error in margin property.

The inline CSS contains invalid syntax: margin: 0, auto uses a comma instead of a space. This will not render as intended.

🐛 Proposed fix
-<img style="width: 50%; height: auto; margin: 0, auto" src="./images/slider/cookie-00.jpg"/>
+<img style="width: 50%; height: auto; margin: 0 auto" src="./images/slider/cookie-00.jpg"/>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@website/blog/2018/12/12.25-gardener-cookies.md` at line 17, The inline img
element uses an invalid CSS value "margin: 0, auto"; update the style on the
<img> (the tag with src="./images/slider/cookie-00.jpg") to use a valid margin
declaration "margin: 0 auto" (and keep the rest: "width: 50%; height: auto") so
the image is properly centered.
♻️ Duplicate comments (1)
website/blog/2022/02/02.17-gardener-community-meeting-february.md (1)

36-37: ⚠️ Potential issue | 🟠 Major

Hugo shortcode syntax not converted.

This file still contains Hugo shortcode syntax {{< youtube ... >}} which should be converted to VitePress component format per the PR objectives.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@website/blog/2022/02/02.17-gardener-community-meeting-february.md` around
lines 36 - 37, The file contains a Hugo shortcode "{{< youtube
id=\"U1VvyQiE3Jg\" title=\"Gardenctl-v2\" >}}" that wasn't converted to
VitePress format; replace that Hugo shortcode with the VitePress YouTube
component (use the YouTube component with id and title props) so the embedded
video uses the new VitePress component system and renders correctly.
🧹 Nitpick comments (4)
website/blog/2018/06/06.11-auditing-kubernetes-for-secure-setup.md (1)

9-12: Tags implementation looks good!

The YAML syntax is correct and the tags are properly formatted. The technical-deep-dive and security tags align well with the post's content about security auditing and penetration testing.

The networking tag is more tangential—while the post mentions "network air gap," the primary focus is on security auditing rather than networking concepts. Consider whether this tag adds value for users filtering by networking topics.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@website/blog/2018/06/06.11-auditing-kubernetes-for-secure-setup.md` around
lines 9 - 12, The tags list includes a tangential "networking" tag; review the
post's focus and either remove "networking" from the YAML tags array or replace
it with a more relevant tag (e.g., "compliance" or "audit") by editing the tags
block where "technical-deep-dive", "security", and "networking" are defined so
the metadata accurately reflects the article's primary focus.
website/documentation/contribute/documentation/blog-tags.md (1)

1-59: LGTM! Clear and comprehensive tag taxonomy.

The documentation provides a well-structured reference for blog tagging with clear categorization and consistent formatting. The lowercase kebab-case convention is explicitly stated and followed throughout.

Consider enhancing the documentation with:

  • Brief usage examples for ambiguous tags (e.g., when to use technical-deep-dive vs. tutorial)
  • Guidance on the recommended number of tags per post
  • Clarification on whether multiple content type tags can be used together
📝 Optional documentation enhancement
 ## Tag Format
 
 Use lowercase kebab-case (`tag-name`) for all tags.
+
+## Tag Selection Guidelines
+
+- Choose 2-5 tags per post for optimal discoverability
+- Include at least one content type tag
+- Add technical domain tags that represent major topics (not every minor mention)
+- Multiple content type tags can be used when content serves multiple purposes (e.g., `tutorial` + `case-study`)
 
 ## Content Type Tags
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@website/documentation/contribute/documentation/blog-tags.md` around lines 1 -
59, Add short clarifying guidance and examples to the blog tag reference: under
"Content Type Tags" add a one-sentence example for when to use
`technical-deep-dive` versus `tutorial` and an explicit statement about whether
multiple content-type tags (e.g., `feature-announcement` + `release-notes`) are
allowed; add a small "Tag usage" subsection recommending a maximum number of
tags per post (e.g., 3–5) and a one-line rule-of-thumb for selecting primary vs.
secondary tags; place these additions near the existing Content Type Tags block
so readers can quickly map tag names like `case-study`, `community-event`,
`milestone` to concrete use cases.
website/blog/2025/10/10-08-efs-filestore-csi-drivers.md (1)

11-18: Consider reducing the number of tags for better focus.

This post has 7 tags, which is quite comprehensive but may dilute the effectiveness of tag-based filtering. While all tags have some relevance, consider focusing on the 3-4 most essential ones:

  • Core tags: technical-deep-dive, storage, provider-aws, provider-gcp
  • Optional/tangential: security (briefly mentioned), networking (not the primary focus), node-management (indirectly related)

Fewer, more focused tags typically provide better discoverability and user experience.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@website/blog/2025/10/10-08-efs-filestore-csi-drivers.md` around lines 11 -
18, The frontmatter "tags" list is too broad (7 items); reduce it to 3–4 focused
tags by keeping the core ones and removing tangential ones: update the YAML
"tags" value to include "technical-deep-dive", "storage", and either or both
"provider-aws" and "provider-gcp" as applicable, and remove or make optional
"security", "networking", and "node-management" so tag-based filtering is more
effective.
website/blog/2018/12/12.25-gardener-cookies.md (1)

9-11: Consider whether these tags accurately reflect the content.

The tags technical-deep-dive and security seem misaligned with a blog post about a cookie recipe. These tags would typically be used for technical documentation or security-related features, which may confuse users filtering or searching for such content.

If this post is intended to be light-hearted/off-topic content, consider using tags like community or fun instead, or removing tags entirely.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@website/blog/2018/12/12.25-gardener-cookies.md` around lines 9 - 11, The
frontmatter tags currently list technical-deep-dive and security which don't
match a cookie recipe; update the tags array in the post's frontmatter (the tags
key) to more appropriate values—e.g., replace technical-deep-dive and security
with community or fun, or remove the tags entirely—so the tags accurately
reflect this light-hearted/off-topic blog post.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.vitepress/config.mts:
- Around line 305-308: The config sets
'data-modal-override-open-selector-search' to '#local-search' but that ID does
not exist, so the Kapa widget's search button and Cmd/Ctrl+K binding won't find
an element; either add an element with id="local-search" in the theme/layout
where the search modal is rendered (e.g., the header or search component) or
change the selector value in the config to the actual element's selector (the
real search button/modal ID/class) so 'data-modal-override-open-selector-search'
points to a valid DOM node.

In @.vitepress/data/blog.data.ts:
- Around line 55-99: The filter currently computes hasDate but never uses it and
the filename regex only matches MM.DD- patterns, causing undated posts to be
treated as newest; update the .filter callback to include hasDate (return
!isIndex && isNotFolder && hasDate) and broaden the filename regex used both
where hasDate is set and in the .map (replace /\/(\d{4})\/(\d{2})\.(\d{2})-/
with a pattern that accepts either a dot or dash between month and day, e.g.
/\/(\d{4})\/(\d{2})(?:[.-])(\d{2})-/), ensuring the same regex is used for the
initial hasDate computation and the url.match before calling formatDate.
- Around line 209-221: normalizeAuthor currently extracts a GitHub login but
still uses the original string as the display name, causing URLs to render as
names; update the string branch in normalizeAuthor to set name to the extracted
login when getGitHubLogin(trimmed) returns a non-empty login (fall back to
trimmed without leading '@' only if login is empty), and continue to use
toGitHubAvatar(login) for avatar resolution so display name, login and avatar
are consistent.

In @.vitepress/theme/components/BlogIndex.vue:
- Around line 28-61: selectedTags is being populated from window.location.search
at module setup time causing SSR vs client hydration mismatches; change it to
initialize selectedTags as an empty ref and defer calling
parseSelectedTagsFromUrl() to an onMounted() callback. Specifically: import
onMounted from 'vue', set const selectedTags = ref<string[]>([]) (leave tagQuery
as-is), and inside onMounted() call selectedTags.value =
parseSelectedTagsFromUrl() so no window-dependent parsing runs during server
render.

In @.vitepress/theme/components/BlogPostMeta.vue:
- Around line 45-76: The date-only ISO strings are parsed as UTC instants and
toLocaleDateString in toDisplayDate converts them to the viewer's local timezone
causing off-by-one-day for some users; update formatDate/toDisplayDate so that
when the input is a date-only string (e.g., parsed from formatDate's new
Date(trimmed) where trimmed matches /^\d{4}-\d{2}-\d{2}$/) you format using the
date's UTC components (getUTCFullYear/getUTCMonth/getUTCDate) or explicitly
build a Date at UTC midnight and format those UTC fields into the "Month D,
YYYY" string instead of relying on toLocaleDateString on a local-time Date; keep
toDisplayDate or add a toDisplayDateUTC helper and call it from formatDate for
date-only inputs and leave non-date-only behavior unchanged.

In `@hack/apply-blog-tags.mjs`:
- Around line 18-41: The taxonomy provider slugs in TAXONOMY_ORDER are
inconsistent with the front-matter (they use 'aws', 'azure', 'gcp',
'openstack'); update those entries to 'provider-aws', 'provider-azure',
'provider-gcp', 'provider-openstack' so they match the post front-matter; also
make the same replacement in the other provider tag list later in the file (the
provider tag array used around lines 87-93) so the script won't create duplicate
provider buckets when run.

In `@tmp-blog-page.html`:
- Around line 1-15: Delete the temporary development artifact tmp-blog-page.html
(it contains dev-only paths like "/@vite/client" and
"/@fs/app/node_modules/vitepress/dist/client/app/index.js") and remove any
references to it; instead add tmp-blog-page.html (or the tmp-*.html pattern) to
.gitignore to prevent committing dev-only files, and verify the build
configuration and project entry points do not rely on the id="app" placeholder
or these Vite dev paths before removing.

In `@website/blog/2018/12/12.22-cookies-are-dangerous.md`:
- Around line 9-11: The post's front-matter tags currently list
technical-deep-dive and security which are incorrect for a baking/holiday piece;
update the YAML tags block (the "tags:" list) to either remove tags entirely or
replace them with appropriate labels such as "community", "culture", "holiday",
"food", or "team" to reflect the edible cookies content so users filtering by
technical/security tags are not misled.

In `@website/blog/2022/03/03.23-gardener-community-meeting-march.md`:
- Around line 40-43: Replace the Hugo shortcode usage "{{< youtube
id="nV_JI8YWwY4" title="Deploying and Developing Gardener Locally (Without Any
External Infrastructure!)" >}}" with the VitePress component syntax for
embedding YouTube (e.g., the project's YouTube or Video component) so the video
renders after the "Recording" heading; update the line that contains the youtube
shortcode to call the VitePress component (passing id="nV_JI8YWwY4" and title as
props) consistent with other VitePress component usages in the repo.

In `@website/blog/2022/06/06.17-gardener-community-meeting-june.md`:
- Line 36: Several blog files (including
website/blog/2022/06/06.17-gardener-community-meeting-june.md) still contain
Hugo YouTube shortcodes like {{< youtube id="nG2FRYL05mc" title="..." >}}; run
the automated converter by executing the post-processing script to replace these
with the VitePress component format (<YouTubeVideo videoId="nG2FRYL05mc" />).
Specifically run node post-processing/part-1.js --youtube which invokes the
replaceYouTubeShortcodes() function to transform all occurrences across affected
posts; verify the resulting files contain the <YouTubeVideo videoId="..."/>
component and commit the changes.

In `@website/blog/2022/10/10.06-gardener-community-meeting-october.md`:
- Line 38: The Hugo youtube shortcode "{{< youtube id="46nCdVA-rsc"
title="Cilium / Isovalent Presentation" >}}" was not converted to the VitePress
component; replace this shortcode with the project's VitePress YouTube component
(e.g., the component used across the repo such as <YouTube .../>), passing the
same id ("46nCdVA-rsc") and title ("Cilium / Isovalent Presentation") props so
the video renders correctly; apply the same fix to the other blog files that
still contain Hugo youtube shortcodes.

In `@website/blog/2022/10/10.20-gardener-community-meeting-october-2.md`:
- Around line 34-35: Replace the Hugo shortcode {{< youtube id="5a_A3furzlg"
title="Get more computing power in Gardener with CRI-resource-manager" >}} with
the VitePress component equivalent (e.g., <YouTube id="5a_A3furzlg" title="Get
more computing power in Gardener with CRI-resource-manager" /> or the project's
defined <YouTube> component syntax), ensuring proper self-closing or explicit
opening/closing tags per the VitePress setup; apply the same replacement to the
other blog files that still contain Hugo shortcodes (06.17, 02.17, 10.06, 03.23)
so all shortcodes are converted consistently.

In `@website/blog/2024/11/11-09-demo.md`:
- Around line 23-25: Frontmatter includes an inappropriate tag: the
"observability" tag in the "tags:" block should be replaced with a more relevant
tag; update the frontmatter where "tags:" is defined to remove "observability"
and add a suitable alternative such as "getting-started", "tutorial", or
"community" (choose one consistent with your site's taxonomy) so the post about
the Gardener demo environment is correctly classified.

In
`@website/blog/2025/05/05-19-gardener-dashboard-180-streamlined-credentials-enhanced-cluster-views-and-real-time-updates.md`:
- Around line 11-15: Remove the incorrect "cost-optimization" tag from the tags
frontmatter block (the tags: list that currently includes feature-announcement,
cost-optimization, security, dashboard) so the post isn't surfaced under
cost-focused filters; if you intend to keep it, instead add a cost-specific
section to the article that justifies keeping "cost-optimization".

In
`@website/blog/2025/06/06-18-enhanced-internal-traffic-management-l7-load-balancing-for-kube-apiservers-in-gardener.md`:
- Around line 11-14: The front-matter tags list contains an incorrect "storage"
tag; remove the "storage" entry from the tags array in the article metadata (the
YAML block starting with "tags:") so only relevant tags remain (e.g., keep
"feature-announcement" and "networking") and ensure the YAML remains valid after
removing the "- storage" line.

In `@website/blog/2025/09/09-10-explicit-internal-dns-configuration-for-seeds.md`:
- Around line 11-15: The front-matter tags list includes a misleading
provider-specific tag "provider-aws"; remove "provider-aws" from the tags array
in the post's front-matter (the YAML block that currently lists tags:
technical-deep-dive, security, networking, provider-aws) so the article remains
provider-agnostic—simply delete the provider-aws entry and ensure the tags
remain valid YAML (comma-separated list or YAML sequence) with the other tags
unchanged.

In `@website/documentation/resources/videos/livecheck-readiness.md`:
- Line 8: The markdown uses the Hugo YouTube shortcode {{< youtube
id="mxEvAPQRwhw" title="Readiness != Liveness" >}} but the post-processing step
in part-1.js (invoked with the --youtube flag) is not guaranteed to run
automatically; either ensure the post-processing script is invoked as part of
the standard build pipeline (add the part-1.js --youtube invocation to the build
step in CI/npm scripts) or replace the shortcode in this file and the other
affected markdowns with the VitePress YouTube component syntax before merging so
the pages render correctly without manual post-processing.

---

Outside diff comments:
In `@website/blog/2018/06/06.11-shared-storage-with-s3-backend.md`:
- Line 20: Replace the transitional adverb "However" at the start of the
sentence "However, it can be used to import and parse large amounts of data into
a database." with a more appropriate connector such as "Additionally," or
"Furthermore," (or "For example," if you intend to illustrate a use case) so the
sentence reads e.g. "Additionally, it can be used to import and parse large
amounts of data into a database." This change improves cohesion without altering
the sentence content.

In `@website/blog/2018/12/12.25-gardener-cookies.md`:
- Line 17: The inline img element uses an invalid CSS value "margin: 0, auto";
update the style on the <img> (the tag with src="./images/slider/cookie-00.jpg")
to use a valid margin declaration "margin: 0 auto" (and keep the rest: "width:
50%; height: auto") so the image is properly centered.

---

Duplicate comments:
In `@website/blog/2022/02/02.17-gardener-community-meeting-february.md`:
- Around line 36-37: The file contains a Hugo shortcode "{{< youtube
id=\"U1VvyQiE3Jg\" title=\"Gardenctl-v2\" >}}" that wasn't converted to
VitePress format; replace that Hugo shortcode with the VitePress YouTube
component (use the YouTube component with id and title props) so the embedded
video uses the new VitePress component system and renders correctly.

---

Nitpick comments:
In `@website/blog/2018/06/06.11-auditing-kubernetes-for-secure-setup.md`:
- Around line 9-12: The tags list includes a tangential "networking" tag; review
the post's focus and either remove "networking" from the YAML tags array or
replace it with a more relevant tag (e.g., "compliance" or "audit") by editing
the tags block where "technical-deep-dive", "security", and "networking" are
defined so the metadata accurately reflects the article's primary focus.

In `@website/blog/2018/12/12.25-gardener-cookies.md`:
- Around line 9-11: The frontmatter tags currently list technical-deep-dive and
security which don't match a cookie recipe; update the tags array in the post's
frontmatter (the tags key) to more appropriate values—e.g., replace
technical-deep-dive and security with community or fun, or remove the tags
entirely—so the tags accurately reflect this light-hearted/off-topic blog post.

In `@website/blog/2025/10/10-08-efs-filestore-csi-drivers.md`:
- Around line 11-18: The frontmatter "tags" list is too broad (7 items); reduce
it to 3–4 focused tags by keeping the core ones and removing tangential ones:
update the YAML "tags" value to include "technical-deep-dive", "storage", and
either or both "provider-aws" and "provider-gcp" as applicable, and remove or
make optional "security", "networking", and "node-management" so tag-based
filtering is more effective.

In `@website/documentation/contribute/documentation/blog-tags.md`:
- Around line 1-59: Add short clarifying guidance and examples to the blog tag
reference: under "Content Type Tags" add a one-sentence example for when to use
`technical-deep-dive` versus `tutorial` and an explicit statement about whether
multiple content-type tags (e.g., `feature-announcement` + `release-notes`) are
allowed; add a small "Tag usage" subsection recommending a maximum number of
tags per post (e.g., 3–5) and a one-line rule-of-thumb for selecting primary vs.
secondary tags; place these additions near the existing Content Type Tags block
so readers can quickly map tag names like `case-study`, `community-event`,
`milestone` to concrete use cases.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b6be578c-987f-4709-9128-40d6b391e834

📥 Commits

Reviewing files that changed from the base of the PR and between c21c3ff and 420217a.

📒 Files selected for processing (96)
  • .vitepress/config.mts
  • .vitepress/data/blog.data.ts
  • .vitepress/theme/components/BlogIndex.vue
  • .vitepress/theme/components/BlogPostMeta.vue
  • .vitepress/theme/index.ts
  • hack/apply-blog-tags.mjs
  • hack/preview.sh
  • tmp-blog-page.html
  • website/blog/2018/06/06.11-anti-patterns.md
  • website/blog/2018/06/06.11-auditing-kubernetes-for-secure-setup.md
  • website/blog/2018/06/06.11-big-things-come-in-small-packages.md
  • website/blog/2018/06/06.11-hardening-the-gardener-community-setup.md
  • website/blog/2018/06/06.11-kubernetes-is-available-in-docker-for-mac-17-12-ce.md
  • website/blog/2018/06/06.11-namespace-isolation.md
  • website/blog/2018/06/06.11-namespace-scope.md
  • website/blog/2018/06/06.11-readwritemany-dynamically-provisioned-persistent-volumes-using-amazon-efs.md
  • website/blog/2018/06/06.11-shared-storage-with-s3-backend.md
  • website/blog/2018/06/06.11-watching-logs-of-several-pods.md
  • website/blog/2018/07/07.11-hibernate-a-cluster-to-save-money.md
  • website/blog/2018/12/12.22-cookies-are-dangerous.md
  • website/blog/2018/12/12.25-gardener-cookies.md
  • website/blog/2019/05/05.24-cluster-api-machine-abstractions-kubecon-talk.md
  • website/blog/2019/06/06.11-feature-flags-in-kubernetes-applications.md
  • website/blog/2019/06/06.11-organizing-access-using-kubeconfig-files.md
  • website/blog/2020/05/05.11-new-website-same-green-flower.md
  • website/blog/2020/08/08.06-gardener-v1.8.0-released.md
  • website/blog/2020/09/09.11-gardener-v1.9-and-v1.10-released.md
  • website/blog/2020/10/10.19-gardener-integrates-with-kubevirt.md
  • website/blog/2020/10/10.19-shoot-reconciliation-details.md
  • website/blog/2020/11/11.04-gardener-v1.11-and-v1.12-released.md
  • website/blog/2020/11/11.20-case-study-migrating-etcd-volumes-in-production.md
  • website/blog/2020/11/11.23-gardener-v1.13-released.md
  • website/blog/2020/12/12.03-stackit-kubernetes-engine-with-gardener.md
  • website/blog/2021/01/01.25-machine-controller-manager.md
  • website/blog/2021/02/02.01-happy-anniversary-gardener.md
  • website/blog/2021/09/09.12-navigating-cloud-native-security.md
  • website/blog/2022/02/02.17-gardener-community-meeting-february.md
  • website/blog/2022/03/03.23-gardener-community-meeting-march.md
  • website/blog/2022/06/06.17-gardener-community-meeting-june.md
  • website/blog/2022/10/10.06-gardener-community-meeting-october.md
  • website/blog/2022/10/10.20-gardener-community-meeting-october-2.md
  • website/blog/2023/03/03-27-high-availability-and-zone-outage-toleration.md
  • website/blog/2024/04/04-05-kubecon-cloudnativecon-europe-2024-highlights.md
  • website/blog/2024/04/04-18-spinkube-gardener-shoot-cluster.md
  • website/blog/2024/04/04-22-gardener's-registry-cache-extension-another-cost-saving-win-and-more.md
  • website/blog/2024/05/05-21-innovation-unleashed-a-deep-dive-into-the-5th-gardener-community-hackathon.md
  • website/blog/2024/10/10-24-gardener-kubecon-cloudnativecon-na-2024-announcement.md
  • website/blog/2024/11/11-06-promcon-eu-2024.md
  • website/blog/2024/11/11-09-demo.md
  • website/blog/2024/12/12-08-unleashing-potential-highlights-from-the-6th-gardener-community-hackathon.md
  • website/blog/2025/03/03-18-gardener-kubecon-cloudnativecon-europe-2025-announcement.md
  • website/blog/2025/04/04-17-leaner-clusters-lower-bills.md
  • website/blog/2025/05/05-12-gardener-neonephos.md
  • website/blog/2025/05/05-19-enhanced-network-flexibility-gardener-now-supports-cidr-overlap-for-non-ha-shoots.md
  • website/blog/2025/05/05-19-enhanced-node-management-introducing-in-place-updates-in-gardener.md
  • website/blog/2025/05/05-19-gardener-dashboard-180-streamlined-credentials-enhanced-cluster-views-and-real-time-updates.md
  • website/blog/2025/05/05-21-fine-tuning-kube-proxy-readiness-ensuring-accurate-health-checks-during-node-scale-down.md
  • website/blog/2025/05/05-21-new-in-gardener-forceful-redeployment-of-gardenlets-for-enhanced-operational-control.md
  • website/blog/2025/05/05-21-streamlined-node-onboarding-introducing-gardenadm-token-and-gardenadm-join.md
  • website/blog/2025/06/06-17-taking-gardener-to-the-next-level-highlights-from-the-7th-gardener-community-hackathon-in-schelklingen.md
  • website/blog/2025/06/06-18-enabling-seamless-ipv4-to-dual-stack-migration-for-kubernetes-clusters-on-gcp.md
  • website/blog/2025/06/06-18-enhanced-extension-management-introducing-autoenable-and-clustercompatibility.md
  • website/blog/2025/06/06-18-enhanced-internal-traffic-management-l7-load-balancing-for-kube-apiservers-in-gardener.md
  • website/blog/2025/06/06-18-gardener-enhances-observability-with-opentelemetry-integration-for-logging.md
  • website/blog/2025/06/06-25-enhanced-health-checks-for-node-rolling-updates.md
  • website/blog/2025/06/06-25-enhancing-meltdown-protection-with-dependency-watchdog-annotations.md
  • website/blog/2025/06/06-25-improving-credential-management-for-seed-backups.md
  • website/blog/2025/06/06-25-introducing-gardenadm-bootstrap-for-autonomous-shoots.md
  • website/blog/2025/06/06-30-getting-started-with-opentelemetry-on-gardener-shoot-cluster.md
  • website/blog/2025/07/07-16-enhancing-data-protection-with-immutable-backup-buckets.md
  • website/blog/2025/07/07-30-enhanced-network-flexibility-cidr-overlap-now-supported-for-ha-shoots.md
  • website/blog/2025/08/08-04-cluster-api-provider-gardener.md
  • website/blog/2025/08/08-13-keeping-track-of-your-resources-with-inventory.md
  • website/blog/2025/08/08-27-enabling-node-local-dns-without-node-rollouts.md
  • website/blog/2025/08/08-27-new-emergency-brake-for-gardener-shoot-reconciliations.md
  • website/blog/2025/09/09-05-ipv6-update.md
  • website/blog/2025/09/09-10-explicit-internal-dns-configuration-for-seeds.md
  • website/blog/2025/09/09-10-modernizing-gardeners-logging-stack-with-opentelemetry.md
  • website/blog/2025/10/10-08-efs-filestore-csi-drivers.md
  • website/blog/2025/10/10-22-extensible-advertised-addresses-for-shoots.md
  • website/blog/2025/10/10-22-useunifiedhttpproxy-feature-gate.md
  • website/blog/2025/10/10-27-unifying-dns-behavior-custom-coredns-configurations-now-supported-in-node-local-dns.md
  • website/blog/2025/11/11-12-gardener-ai-conformance.md
  • website/blog/2025/11/11-13-promcon-eu-2025.md
  • website/blog/2026/01/01-28-introducing-automated-credential-rotation.md
  • website/blog/2026/02/02-18-enhanced-security-for-helm-deployments-gardener-adds-custom-ca-support-for-oci-registries.md
  • website/blog/2026/02/02-18-seamlessly-switch-calicos-overlay-network-in-gardener.md
  • website/blog/2026/02/02-18-simplify-multi-cluster-configuration-with-static-manifest-propagation.md
  • website/blog/index.md
  • website/documentation/contribute/documentation/blog-tags.md
  • website/documentation/resources/videos/in-out-networking.md
  • website/documentation/resources/videos/livecheck-readiness.md
  • website/documentation/resources/videos/microservices-in_kubernetes.md
  • website/documentation/resources/videos/namespace.md
  • website/documentation/resources/videos/small-container.md
  • website/documentation/resources/videos/why-kubernetes.md
💤 Files with no reviewable changes (1)
  • website/blog/index.md

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (1)
website/blog/2018/12/12.22-cookies-are-dangerous.md (1)

9-10: Significant improvement: misleading technical tags removed.

The previous critical issue has been resolved—technical-deep-dive and security tags have been replaced with community-event. While community-event is defined as "Community meeting, conference, or hackathon updates" (per the blog tag reference documentation in website/documentation/contribute/documentation/blog-tags.md), this tag is the closest fit among the available content-type tags for this informal Christmas team event post.

Optional refinement: If the tagging system evolves to include a team-culture or informal tag, this post might be a good candidate for reclassification.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@website/blog/2018/12/12.22-cookies-are-dangerous.md` around lines 9 - 10,
Update the post's YAML frontmatter tags to reflect the event nature by removing
technical tags and using the community-focused tag value currently set as
"community-event"; in the frontmatter ensure the "tags:" key contains only
appropriate content-type tags (replace "technical-deep-dive" and "security" with
"community-event"), and consider adding a future "team-culture" or "informal"
tag when the tagging taxonomy expands.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.vitepress/data/blog.data.ts:
- Around line 261-280: The loader currently only reads rawAuthor.avatar; update
the avatar resolution so it honors authors[].image too by computing avatar =
asNonEmptyString(rawAuthor.image) || asNonEmptyString(rawAuthor.avatar) ||
toGitHubAvatar(login). Change the avatar assignment (where avatar is declared)
to check rawAuthor.image first, then rawAuthor.avatar, then fallback to
toGitHubAvatar(login) and keep using asNonEmptyString(...) to validate values;
no other logic changes needed.

In @.vitepress/theme/components/BlogIndex.vue:
- Around line 63-65: The selectedTags state is initialized from
parseSelectedTagsFromUrl in onMounted but not written back when the user changes
filters, so toggleTag() and clearFilters() must also update the URL query;
locate the selectedTags state and add a single reactive sync (either by adding a
watch on selectedTags or by updating the query inside toggleTag() and
clearFilters()) that writes the current tag set to the query string (e.g.,
update the "tag" param with the joined tags or remove it when empty) using the
router (useRouter().replace) or history.replaceState so the address always
reflects the active tag set; ensure parseSelectedTagsFromUrl still reads that
same query on mount.

In @.vitepress/theme/components/BlogPostMeta.vue:
- Around line 35-36: The code is currently passing non-ISO, human-readable
strings (e.g., frontmatter.value.newsSubtitle) into formatDate which parses them
with local-time new Date and then formats to UTC, causing off-by-one-day issues
for timezones ahead of UTC; update the logic around formatDate (and the call
site using frontmatter.value.publishdate / frontmatter.value.date /
frontmatter.value.newsSubtitle) to detect non-ISO inputs and either (a) use the
already pre-formatted human-readable string as-is (return newsSubtitle
unchanged) or (b) normalize inputs to a proper ISO date before parsing; ensure
formatDate only parses ISO strings (or remove UTC conversion for non-ISO display
strings) so calendar dates aren’t shifted for users in UTC+ timezones.

In `@hack/apply-blog-tags.mjs`:
- Around line 122-128: The fallback tag 'technical-deep-dive' is being applied
based only on inferredTags before merge, which can cause duplicate content-type
tags; instead, remove the current check and after computing mergedTags =
mergeTags(inferredTags, existingTags) add the fallback only if mergedTags.length
=== 0 so the fallback is added only when neither heuristics nor frontmatter
produced any tags. Update the code around inferTags, normalizeTags and mergeTags
usage so the conditional check for adding 'technical-deep-dive' occurs after
mergeTags returns the final mergedTags.

---

Nitpick comments:
In `@website/blog/2018/12/12.22-cookies-are-dangerous.md`:
- Around line 9-10: Update the post's YAML frontmatter tags to reflect the event
nature by removing technical tags and using the community-focused tag value
currently set as "community-event"; in the frontmatter ensure the "tags:" key
contains only appropriate content-type tags (replace "technical-deep-dive" and
"security" with "community-event"), and consider adding a future "team-culture"
or "informal" tag when the tagging taxonomy expands.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a00bf0f1-e3cd-4c22-aad1-4ce0c7381013

📥 Commits

Reviewing files that changed from the base of the PR and between 420217a and 213122c.

📒 Files selected for processing (11)
  • .vitepress/data/blog.data.ts
  • .vitepress/theme/components/BlogIndex.vue
  • .vitepress/theme/components/BlogPostMeta.vue
  • hack/apply-blog-tags.mjs
  • hack/preview.sh
  • website/blog/2018/12/12.22-cookies-are-dangerous.md
  • website/blog/2018/12/12.25-gardener-cookies.md
  • website/blog/2024/11/11-09-demo.md
  • website/blog/2025/05/05-19-enhanced-network-flexibility-gardener-now-supports-cidr-overlap-for-non-ha-shoots.md
  • website/blog/2025/06/06-18-enhanced-internal-traffic-management-l7-load-balancing-for-kube-apiservers-in-gardener.md
  • website/blog/2025/09/09-10-explicit-internal-dns-configuration-for-seeds.md
🚧 Files skipped from review as they are similar to previous changes (5)
  • hack/preview.sh
  • website/blog/2025/05/05-19-enhanced-network-flexibility-gardener-now-supports-cidr-overlap-for-non-ha-shoots.md
  • website/blog/2025/09/09-10-explicit-internal-dns-configuration-for-seeds.md
  • website/blog/2024/11/11-09-demo.md
  • website/blog/2018/12/12.25-gardener-cookies.md

Comment on lines +261 to +280
const rawAuthor = value as {
name?: unknown
avatar?: unknown
login?: unknown
github?: unknown
url?: unknown
}

const explicitName = asNonEmptyString(rawAuthor.name)
const login = getGitHubLogin(rawAuthor.login)
?? getGitHubLogin(rawAuthor.github)
?? getGitHubLogin(rawAuthor.url)
const name = explicitName || login

if (!name) {
return undefined
}

// Normal case - valid date
date.setUTCHours(12);
const avatar = asNonEmptyString(rawAuthor.avatar) || toGitHubAvatar(login)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Honor authors[].image on the index cards too.

BlogPostMeta.vue accepts both avatar and image, but this loader only reads avatar. An author defined with image: will therefore get a photo on the post page and no photo in the listing.

💡 Possible fix
   const rawAuthor = value as {
     name?: unknown
     avatar?: unknown
+    image?: unknown
     login?: unknown
     github?: unknown
     url?: unknown
   }
@@
-  const avatar = asNonEmptyString(rawAuthor.avatar) || toGitHubAvatar(login)
+  const avatar =
+    asNonEmptyString(rawAuthor.avatar)
+    || asNonEmptyString(rawAuthor.image)
+    || toGitHubAvatar(login)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.vitepress/data/blog.data.ts around lines 261 - 280, The loader currently
only reads rawAuthor.avatar; update the avatar resolution so it honors
authors[].image too by computing avatar = asNonEmptyString(rawAuthor.image) ||
asNonEmptyString(rawAuthor.avatar) || toGitHubAvatar(login). Change the avatar
assignment (where avatar is declared) to check rawAuthor.image first, then
rawAuthor.avatar, then fallback to toGitHubAvatar(login) and keep using
asNonEmptyString(...) to validate values; no other logic changes needed.

Comment on lines +63 to +65
onMounted(() => {
selectedTags.value = parseSelectedTagsFromUrl()
})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Keep the query string synced with the active tag set.

The page can start from /blog/?tag=..., but toggleTag() and clearFilters() only mutate local state. After the user adds or clears tags, reloading or copying the address restores a different filter set than the UI shows.

🛠️ Possible fix
+function syncSelectedTagsToUrl(): void {
+  if (typeof window === 'undefined') {
+    return
+  }
+
+  const url = new URL(window.location.href)
+  url.searchParams.delete('tag')
+  url.searchParams.delete('tags')
+
+  for (const tag of selectedTags.value) {
+    url.searchParams.append('tag', tag)
+  }
+
+  window.history.replaceState({}, '', url)
+}
+
 function toggleTag(tag: string): void {
   const existingIndex = selectedTags.value.findIndex(selected => selected.toLowerCase() === tag.toLowerCase())
@@
   // Clicking tags manages the selected tag set explicitly.
   tagQuery.value = ''
+  syncSelectedTagsToUrl()
 }
 
 function clearFilters(): void {
   selectedTags.value = []
   tagQuery.value = ''
+  syncSelectedTagsToUrl()
 }

Also applies to: 126-141

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.vitepress/theme/components/BlogIndex.vue around lines 63 - 65, The
selectedTags state is initialized from parseSelectedTagsFromUrl in onMounted but
not written back when the user changes filters, so toggleTag() and
clearFilters() must also update the URL query; locate the selectedTags state and
add a single reactive sync (either by adding a watch on selectedTags or by
updating the query inside toggleTag() and clearFilters()) that writes the
current tag set to the query string (e.g., update the "tag" param with the
joined tags or remove it when empty) using the router (useRouter().replace) or
history.replaceState so the address always reflects the active tag set; ensure
parseSelectedTagsFromUrl still reads that same query on mount.

Comment on lines +35 to +36
const raw = frontmatter.value.publishdate || frontmatter.value.date || frontmatter.value.newsSubtitle
return formatDate(raw)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🌐 Web query:

In browser JavaScript, if code does new Date("June 18, 2025")and then formats it withtoLocaleDateString("en-US", { timeZone: "UTC" }), can users in time zones ahead of UTC see the previous calendar day?

💡 Result:

Yes—it can happen, in the common case where the browser parses "June 18, 2025" as midnight in the user’s local time zone.

  • Non‑ISO date strings like "June 18, 2025" are implementation-defined, and implementations “usually default to the local time zone” when parsing them. [1]
  • toLocaleDateString(..., { timeZone: "UTC" }) formats the same instant as a UTC calendar date (via Intl.DateTimeFormat’s timeZone option). [2]

So for a user ahead of UTC (positive offset), local midnight can be the previous day in UTC. Example (UTC+10):

  • Parsed instant: 2025‑06‑18 00:00 (UTC+10) = 2025‑06‑17 14:00Z
  • Formatting in UTC prints 6/17/2025 (previous calendar day).

To avoid this, don’t rely on non‑ISO parsing; use an ISO string with an explicit zone (e.g. "2025-06-18T00:00:00Z") or construct via UTC components. [1]

Sources: [1] MDN Date.parse() (non‑standard strings are implementation-defined; commonly parsed in local time), [2] MDN Intl.DateTimeFormat() constructor (timeZone option, including "UTC").


🏁 Script executed:

cat .vitepress/theme/components/BlogPostMeta.vue

Repository: gardener/documentation

Length of output: 7940


Don't round-trip human-readable dates through Date and UTC formatting.

The ISO path is correctly handled using Date.UTC() at lines 60–63, but non-ISO strings like newsSubtitle values ("June 18, 2025") at lines 64–68 are parsed with new Date(trimmed) in the browser's local timezone, then formatted in UTC. For readers in timezones ahead of UTC (UTC+1 and beyond), this shifts the displayed calendar day backward by one day. For example, a UTC+10 user sees "June 17" instead of "June 18" because the local midnight (June 18, 00:00+10:00) is actually June 17 in UTC. Use ISO date format consistently or return pre-formatted display strings as-is to avoid the mismatch.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.vitepress/theme/components/BlogPostMeta.vue around lines 35 - 36, The code
is currently passing non-ISO, human-readable strings (e.g.,
frontmatter.value.newsSubtitle) into formatDate which parses them with
local-time new Date and then formats to UTC, causing off-by-one-day issues for
timezones ahead of UTC; update the logic around formatDate (and the call site
using frontmatter.value.publishdate / frontmatter.value.date /
frontmatter.value.newsSubtitle) to detect non-ISO inputs and either (a) use the
already pre-formatted human-readable string as-is (return newsSubtitle
unchanged) or (b) normalize inputs to a proper ISO date before parsing; ensure
formatDate only parses ISO strings (or remove UTC conversion for non-ISO display
strings) so calendar dates aren’t shifted for users in UTC+ timezones.

Comment on lines +122 to +128
const inferredTags = inferTags(frontmatter, body, file)
const existingTags = normalizeTags(frontmatter.tags)
const mergedTags = mergeTags(inferredTags, existingTags)

if (mergedTags.length === 0) {
mergedTags.push('technical-deep-dive')
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Move the technical-deep-dive fallback after the merge.

Right now the fallback is decided from inferred tags only. If a post already has a curated content-type tag in front matter but the heuristics miss it, rerunning the script will add a second content-type tag and change the taxonomy unexpectedly.

🛠️ Possible fix
     const inferredTags = inferTags(frontmatter, body, file)
     const existingTags = normalizeTags(frontmatter.tags)
-    const mergedTags = mergeTags(inferredTags, existingTags)
-
-    if (mergedTags.length === 0) {
-      mergedTags.push('technical-deep-dive')
-    }
+    let mergedTags = mergeTags(inferredTags, existingTags)
+
+    if (!mergedTags.some(tag => CONTENT_TYPE_TAGS.includes(tag.toLowerCase()))) {
+      mergedTags = mergeTags(['technical-deep-dive'], mergedTags)
+    }
@@
-  if (!tags.some(tag => CONTENT_TYPE_TAGS.includes(tag))) {
-    tags.push('technical-deep-dive')
-  }
-
   applyRules(tags, focusText, DOMAIN_RULES)

Also applies to: 188-190

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@hack/apply-blog-tags.mjs` around lines 122 - 128, The fallback tag
'technical-deep-dive' is being applied based only on inferredTags before merge,
which can cause duplicate content-type tags; instead, remove the current check
and after computing mergedTags = mergeTags(inferredTags, existingTags) add the
fallback only if mergedTags.length === 0 so the fallback is added only when
neither heuristics nor frontmatter produced any tags. Update the code around
inferTags, normalizeTags and mergeTags usage so the conditional check for adding
'technical-deep-dive' occurs after mergeTags returns the final mergedTags.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (1)
website/documentation/contribute/documentation/style-guide/_index.md (1)

98-117: Consider adding field descriptions and examples.

While the YAML template provides a good starting point, contributors would benefit from:

  • Brief descriptions of what each field is used for (e.g., "publishdate controls the post's publish date and sorting order")
  • A concrete example with real values instead of just placeholders
  • Guidance on the newsSubtitle field format (it appears to be a date string based on the example, but the relationship to publishdate is unclear)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@website/documentation/contribute/documentation/style-guide/_index.md` around
lines 98 - 117, Add short descriptions for each YAML field (title, newsSubtitle,
publishdate, authors, tags) and include a concrete example with real values to
replace placeholders; explicitly state the expected format for newsSubtitle
(e.g., "Month DD, YYYY") and clarify its relationship to publishdate
(publishdate is the machine-readable ISO date used for sorting/URL generation,
newsSubtitle is a human-readable display string), and show one full example
block demonstrating these formats and a filled authors entry (avatar, login,
email, name).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@website/blog/2018/12/12.25-gardener-cookies.md`:
- Line 16: The <img> element in the blog post (the tag shown as <img
style="width: 50%; height: auto; margin: 0 auto"
src="./images/slider/cookie-00.jpg"/>) is missing an alt attribute; add a
concise, descriptive alt text (e.g., alt="Decorative cookies on a plate" or a
description appropriate to the image) to the tag so screen readers receive a
meaningful description.
- Around line 4-8: The front-matter authors block includes unsupported fields;
remove the email and image keys from the authors entry so only supported fields
remain (e.g. keep name and avatar, and add login if needed); locate the authors
block in the markdown (the authors: entry containing name, email, avatar, image)
and delete the email and image lines to match the shape expected by the blog
data importer (which only uses name, avatar, and login).

In `@website/documentation/contribute/documentation/style-guide/_index.md`:
- Line 109: The YAML-style frontmatter line contains a syntax error: the field
"name" currently reads `name: <author-name>>`; remove the extra closing angle
bracket so the line reads `name: <author-name>` to restore valid syntax (locate
the "name" entry in the frontmatter of the documentation/style-guide file and
edit that line).
- Around line 105-109: The author template in
website/documentation/contribute/documentation/style-guide/_index.md includes an
unused email field; update the template to remove the email key and add a short
note listing which Author fields are required vs optional based on the Author
interface in .vitepress/data/blog.data.ts (Author: name required; avatar?
optional; login? optional) so contributors see the correct schema and required
fields.

---

Nitpick comments:
In `@website/documentation/contribute/documentation/style-guide/_index.md`:
- Around line 98-117: Add short descriptions for each YAML field (title,
newsSubtitle, publishdate, authors, tags) and include a concrete example with
real values to replace placeholders; explicitly state the expected format for
newsSubtitle (e.g., "Month DD, YYYY") and clarify its relationship to
publishdate (publishdate is the machine-readable ISO date used for sorting/URL
generation, newsSubtitle is a human-readable display string), and show one full
example block demonstrating these formats and a filled authors entry (avatar,
login, email, name).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b3288f87-e53b-4c74-9d3f-99234aeebe9c

📥 Commits

Reviewing files that changed from the base of the PR and between 213122c and 2258e71.

📒 Files selected for processing (5)
  • website/blog/2018/06/06.11-shared-storage-with-s3-backend.md
  • website/blog/2018/12/12.25-gardener-cookies.md
  • website/blog/2025/10/10-08-efs-filestore-csi-drivers.md
  • website/documentation/contribute/documentation/blog-tags.md
  • website/documentation/contribute/documentation/style-guide/_index.md
🚧 Files skipped from review as they are similar to previous changes (3)
  • website/blog/2025/10/10-08-efs-filestore-csi-drivers.md
  • website/documentation/contribute/documentation/blog-tags.md
  • website/blog/2018/06/06.11-shared-storage-with-s3-backend.md

Comment on lines +4 to +8
authors:
- name: Andreas Herz
email: andreas.herz@sap.com
avatar: https://avatars1.githubusercontent.com/u/1155039?v=4
image: https://avatars1.githubusercontent.com/u/1155039?v=4
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Remove unsupported author fields from front matter.

.vitepress/data/blog.data.ts:40-44 and .vitepress/data/blog.data.ts:260-286 only support name, avatar, and login for authors. In this file, image is a no-op, and email just publishes personal contact data without affecting rendering.

Suggested cleanup
 authors:
 - name: Andreas Herz
-  email: andreas.herz@sap.com
   avatar: https://avatars1.githubusercontent.com/u/1155039?v=4
-  image: https://avatars1.githubusercontent.com/u/1155039?v=4
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
authors:
- name: Andreas Herz
email: andreas.herz@sap.com
avatar: https://avatars1.githubusercontent.com/u/1155039?v=4
image: https://avatars1.githubusercontent.com/u/1155039?v=4
authors:
- name: Andreas Herz
avatar: https://avatars1.githubusercontent.com/u/1155039?v=4
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@website/blog/2018/12/12.25-gardener-cookies.md` around lines 4 - 8, The
front-matter authors block includes unsupported fields; remove the email and
image keys from the authors entry so only supported fields remain (e.g. keep
name and avatar, and add login if needed); locate the authors block in the
markdown (the authors: entry containing name, email, avatar, image) and delete
the email and image lines to match the shape expected by the blog data importer
(which only uses name, avatar, and login).

For a team event during the Christmas season we decided to completely reinterpret the topic `cookies`. :-)

<img style="width: 50%; height: auto; margin: 0, auto" src="./images/slider/cookie-00.jpg"/>
<img style="width: 50%; height: auto; margin: 0 auto" src="./images/slider/cookie-00.jpg"/>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add alt text to the changed image.

The raw HTML image on Line 16 has no alt, so screen readers get no description.

Suggested fix
-<img style="width: 50%; height: auto; margin: 0 auto" src="./images/slider/cookie-00.jpg"/>
+<img style="width: 50%; height: auto; margin: 0 auto" src="./images/slider/cookie-00.jpg" alt="Green tea matcha cookies"/>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<img style="width: 50%; height: auto; margin: 0 auto" src="./images/slider/cookie-00.jpg"/>
<img style="width: 50%; height: auto; margin: 0 auto" src="./images/slider/cookie-00.jpg" alt="Green tea matcha cookies"/>
🧰 Tools
🪛 markdownlint-cli2 (0.21.0)

[warning] 16-16: Images should have alternate text (alt text)

(MD045, no-alt-text)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@website/blog/2018/12/12.25-gardener-cookies.md` at line 16, The <img> element
in the blog post (the tag shown as <img style="width: 50%; height: auto; margin:
0 auto" src="./images/slider/cookie-00.jpg"/>) is missing an alt attribute; add
a concise, descriptive alt text (e.g., alt="Decorative cookies on a plate" or a
description appropriate to the image) to the tag so screen readers receive a
meaningful description.

Comment on lines +105 to +109
authors:
- avatar: <author-profile-picture-link>
login: <author-GitHub-name>
email: <author-email>
name: <author-name>>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Check how author fields (especially email) are consumed in the blog data pipeline and components

# Search for email field usage in blog-related files
echo "=== Searching for 'email' field in blog data and components ==="
rg -n --type=ts --type=vue -C3 'email' -g '*blog*'

# Search for Author interface/type definitions
echo -e "\n=== Searching for Author type definitions ==="
ast-grep --pattern $'interface Author {
  $$$
}'

# Check how authors are processed in blog data
echo -e "\n=== Checking blog data processing ==="
fd -e ts -e js 'blog.data' --exec cat {}

Repository: gardener/documentation

Length of output: 260


🏁 Script executed:

# Search for Author definition in all file types
rg -n "interface Author\|type Author\|class Author" --type-list | head -20

# More general search for "Author"
rg -n "Author" -g "*.ts" -g "*.js" -g "*.tsx" -g "*.jsx" -C 2 | head -50

# Look for author-related configurations
fd -e ts -e js -e json -e yml -e yaml | xargs grep -l -i "author" 2>/dev/null | head -20

Repository: gardener/documentation

Length of output: 857


🏁 Script executed:

# Check the directory structure of the documentation
find website/documentation/contribute -type f -name "*.md" | head -20

# Look at the actual file mentioned in the review
head -120 website/documentation/contribute/documentation/style-guide/_index.md | tail -20

Repository: gardener/documentation

Length of output: 1746


🏁 Script executed:

# Search for email field across all file types
rg -n "email" -C 2 | head -80

# Look for blog or author processing logic
fd -type f \( -name "*.ts" -o -name "*.js" \) -path "*blog*" -o -name "*author*"

Repository: gardener/documentation

Length of output: 7746


🏁 Script executed:

# Search for blog-related TypeScript/JavaScript files
fd -type f \( -name "*.ts" -o -name "*.js" \) | xargs grep -l "author" -i | head -30

Repository: gardener/documentation

Length of output: 236


🏁 Script executed:

# Look for blog data or config files
find . -type f \( -name "*.ts" -o -name "*.js" -o -name "*.json" \) | xargs grep -l "blog" 2>/dev/null | grep -v node_modules | head -20

Repository: gardener/documentation

Length of output: 187


🏁 Script executed:

# Search for more blog posts to see what author fields are actually used
find website/blog -name "*.md" -o -name "*.yml" | head -5 | xargs head -20

Repository: gardener/documentation

Length of output: 4963


🏁 Script executed:

# Look for type definitions or interfaces related to authors
rg -n "interface|type|class" | grep -i "author" | head -20

Repository: gardener/documentation

Length of output: 3955


🏁 Script executed:

# Search in website directory specifically for author-related code
find website -type f \( -name "*.ts" -o -name "*.js" -o -name "*.tsx" \) -exec grep -l "author" {} \;

Repository: gardener/documentation

Length of output: 48


🏁 Script executed:

cat -n ./.vitepress/data/blog.data.ts

Repository: gardener/documentation

Length of output: 16506


Remove the email field from the author template and document which fields are required vs. optional.

The Author interface in .vitepress/data/blog.data.ts (lines 40-44) only defines name (required), avatar? (optional), and login? (optional). The email field in the template is not consumed by the blog system—it's silently ignored during author normalization. Additionally, the template should clarify which fields are required versus optional to guide contributors accurately.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@website/documentation/contribute/documentation/style-guide/_index.md` around
lines 105 - 109, The author template in
website/documentation/contribute/documentation/style-guide/_index.md includes an
unused email field; update the template to remove the email key and add a short
note listing which Author fields are required vs optional based on the Author
interface in .vitepress/data/blog.data.ts (Author: name required; avatar?
optional; login? optional) so contributors see the correct schema and required
fields.

- avatar: <author-profile-picture-link>
login: <author-GitHub-name>
email: <author-email>
name: <author-name>>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix syntax error: Remove extra closing bracket.

Line 109 has a double >> at the end of the placeholder which should be a single >.

📝 Proposed fix
-  name: <author-name>>
+  name: <author-name>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
name: <author-name>>
name: <author-name>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@website/documentation/contribute/documentation/style-guide/_index.md` at line
109, The YAML-style frontmatter line contains a syntax error: the field "name"
currently reads `name: <author-name>>`; remove the extra closing angle bracket
so the line reads `name: <author-name>` to restore valid syntax (locate the
"name" entry in the frontmatter of the documentation/style-guide file and edit
that line).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla: yes Indicates the PR's author has signed the cla-assistant.io CLA. do-not-merge/needs-kind Indicates a PR lacks a `kind/foo` label and requires one. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Improve main blog page layout and content tagging

1 participant