Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .github/workflows/verify-blog.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Verify blog posts
on:
pull_request:
paths:
- 'content/*/blog/**/*.md'
jobs:
markdownlint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0
with:
fetch-depth: 0
- name: Get node version
run: echo "NODE_VERSION=$(make -s print-node-version)" >> $GITHUB_ENV
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e
with:
node-version: ${{ env.NODE_VERSION }}
- run: npm ci
- name: Lint blog posts
run: make lint-blogs BASE_REF=${{ github.base_ref }} LINT_BLOGS_WARN_ONLY=1
15 changes: 15 additions & 0 deletions .markdownlint.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"default": true,
// MD013: Line length — disabled because blog posts have long URLs and prose
"MD013": false,
// MD033: Inline HTML — disabled because Hugo uses HTML shortcodes
"MD033": false,
// MD041: First line heading — disabled because posts start with front matter
"MD041": false,
// MD024: Duplicate headings — disabled because posts reuse subheadings like "Prerequisites"
"MD024": false,
// MD046: Code block style — disabled because Hugo fenced blocks have varied syntax
"MD046": false,
// MD060: Table column style — disabled because it conflicts with readable table formatting
"MD060": false
}
11 changes: 10 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ BLOCK_STDOUT_CMD := python -c "import os,sys,fcntl; \
.DEFAULT_GOAL := help

.PHONY: targets container-targets
targets: help gen-content render server clean clean-all production-build preview-build
targets: help gen-content render server lint-blogs clean clean-all production-build preview-build
container-targets: container-image container-push container-gen-content container-render container-server

help: ## Show this help text.
Expand All @@ -62,6 +62,15 @@ help: ## Show this help text.
dependencies:
npm ci

# Set LINT_BLOGS_WARN_ONLY=1 for advisory lint (CI). Default fails on findings.
LINT_BLOGS_WARN_ONLY ?= 0

lint-blogs: ## Run markdownlint on changed blog posts (LINT_BLOGS_WARN_ONLY=1 for advisory).
LINT_BLOGS_WARN_ONLY=$(LINT_BLOGS_WARN_ONLY) hack/lint-blogs.sh $(BASE_REF)

print-node-version: ## Print the Node.js version used in this project.
@echo $(NODE_VERSION)

gen-content: ## Generates content from external sources.
hack/gen-content.sh

Expand Down
61 changes: 61 additions & 0 deletions hack/lint-blogs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/usr/bin/env bash
# Copyright 2026 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

set -o errexit
set -o nounset
set -o pipefail

BASE_REF="${1:-main}"
LINT_BLOGS_WARN_ONLY="${LINT_BLOGS_WARN_ONLY:-0}"

CHANGED=$(git diff --name-only "origin/${BASE_REF}...HEAD" -- 'content/*/blog/*.md')

if [ -z "${CHANGED}" ]; then
echo "No blog files changed."
exit 0
fi

echo "Linting blog files changed against ${BASE_REF}..."

set +o errexit
OUTPUT=$(echo "${CHANGED}" | xargs markdownlint --config .markdownlint.jsonc 2>&1)
STATUS=$?
set -o errexit

if [ -n "${OUTPUT}" ]; then
printf '%s\n' "${OUTPUT}"
fi

if [ "${STATUS}" -eq 0 ]; then
exit 0
fi

if [ "${LINT_BLOGS_WARN_ONLY}" = "1" ]; then
# markdownlint format: path:line[:column] error RULE message
while IFS= read -r line; do
if [[ "${line}" =~ ^([^:]+):([0-9]+)(:[0-9]+)?[[:space:]]+error[[:space:]]+(.+)$ ]]; then
file="${BASH_REMATCH[1]}"
lineno="${BASH_REMATCH[2]}"
msg="${BASH_REMATCH[4]}"
msg="${msg//'%'/'%25'}"
msg="${msg//$'\r'/}"
echo "::warning file=${file},line=${lineno}::${msg}"
fi
done <<< "${OUTPUT}"
echo "Lint findings treated as warnings (LINT_BLOGS_WARN_ONLY=1)."
exit 0
fi

exit "${STATUS}"
Loading