From 891083543704e6cca5f2faf91665fa7aa72349e5 Mon Sep 17 00:00:00 2001 From: "kirill.chalov" Date: Mon, 1 Jun 2026 15:14:58 +0800 Subject: [PATCH 1/3] ci(article-details): validate lastmod against current date --- tools/ci/check_article_details.sh | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tools/ci/check_article_details.sh b/tools/ci/check_article_details.sh index 69b15b905..fe3c701e9 100644 --- a/tools/ci/check_article_details.sh +++ b/tools/ci/check_article_details.sh @@ -582,6 +582,9 @@ validate_updated_articles() { LASTMOD_DATE=$(awk '/^lastmod:/ { gsub(/["'\'']/, "", $2); print $2 }' "$index_file") ARTICLE_DATE_ONLY="${ARTICLE_DATE:0:10}" + local FILE_MOD_DATE + FILE_MOD_DATE=$(stat -c '%y' "$index_file" 2>/dev/null | cut -d' ' -f1 || stat -f '%Sm' -t '%Y-%m-%d' "$index_file") + echo echo "Article: $index_file" @@ -612,6 +615,18 @@ validate_updated_articles() { fi fi + if [ "$article_error" -eq 0 ] && [ -n "$FILE_MOD_DATE" ]; then + # Calculate days difference (allowing up to 3 days lag) + local days_diff + days_diff=$(( ( $(date -d "$FILE_MOD_DATE" +%s 2>/dev/null || date -j -f "%Y-%m-%d" "$FILE_MOD_DATE" +%s) - $(date -d "$LASTMOD_DATE" +%s 2>/dev/null || date -j -f "%Y-%m-%d" "$LASTMOD_DATE" +%s) ) / 86400 )) + + if [ "$days_diff" -gt 3 ]; then + echo "❌ lastmod is outdated: $LASTMOD_DATE (file modified: $FILE_MOD_DATE)." + echo " Update lastmod to reflect the recent changes (within 3 days of modification)." + article_error=1 + fi + fi + if [ "$article_error" -eq 0 ]; then echo "lastmod date validated successfully." else From aa063a6ef57fadabd5620c8101e726ef2e02301c Mon Sep 17 00:00:00 2001 From: "kirill.chalov" Date: Mon, 1 Jun 2026 17:13:41 +0800 Subject: [PATCH 2/3] ci(article-details) skip front matter changes while checking for lastmod --- tools/ci/check_article_details.sh | 59 +++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 3 deletions(-) diff --git a/tools/ci/check_article_details.sh b/tools/ci/check_article_details.sh index fe3c701e9..ef366cd50 100644 --- a/tools/ci/check_article_details.sh +++ b/tools/ci/check_article_details.sh @@ -565,7 +565,59 @@ validate_author_presence() { # UPDATED ARTICLES VALIDATION ############################################################################### -validate_updated_articles() { +collect_updated_articles_body_only() { + local base_ref="$1" + local output_file="${3:-$TEMP_DIR/index-updated-body.txt}" + + > "$output_file" # Clear output file + + while IFS= read -r file; do + # Skip empty lines + [[ -z "$file" ]] && continue + + # Get the diff for this specific file + local diff_output + diff_output=$(git diff -U0 "$base_ref"...HEAD -- "$file") + + # Flag to track if we found changes in frontmatter + local has_frontmatter_changes=false + + # Parse the diff output looking for change hunks + while IFS= read -r line; do + # Look for hunk headers like @@ -1,5 +1,5 @@ + if [[ "$line" =~ ^@@\ -([0-9]+) ]]; then + local start_line="${BASH_REMATCH[1]}" + + # Get the frontmatter end line from the original file + local frontmatter_end + frontmatter_end=$(git show "$base_ref:$file" | awk ' + BEGIN { count=0 } + /^---$/ { count++; if(count==2) { print NR; exit } } + ') + + # If we couldn't find frontmatter end, assume no frontmatter + [[ -z "$frontmatter_end" ]] && frontmatter_end=0 + + # If this hunk starts within the frontmatter section (line 1 to frontmatter_end) + if [[ $start_line -le $frontmatter_end ]]; then + has_frontmatter_changes=true + break + fi + fi + done <<< "$diff_output" + + # If no frontmatter changes detected, add to output + if [[ "$has_frontmatter_changes" == false ]]; then + echo "$file" >> "$output_file" + fi + done < "$TEMP_DIR/index-updated.txt" + + echo + echo "List of updated articles with body-only changes:" + cat "$output_file" +} + +validate_updated_articles_lastmod() { echo echo "Validating updated articles..." @@ -632,7 +684,7 @@ validate_updated_articles() { else job_error=1 fi - done < "$TEMP_DIR/index-updated.txt" + done < "$TEMP_DIR/index-updated-body.txt" if [ "$job_error" -eq 0 ]; then return 0 @@ -739,7 +791,8 @@ fi banner "🔎 Checking updated files..." if [[ -s "$TEMP_DIR/index-updated.txt" ]]; then - validate_updated_articles || overall_error=1 + collect_updated_articles_body_only "$BASE_REF" + validate_updated_articles_lastmod || overall_error=1 fi if [[ -s "$TEMP_DIR/folders-renamed.txt" ]]; then From 537e9d2750f9ffbd3016415006a931f915f428ac Mon Sep 17 00:00:00 2001 From: "kirill.chalov" Date: Mon, 1 Jun 2026 18:07:19 +0800 Subject: [PATCH 3/3] ci(article-details) prevent trailing whitespaces in new articles --- tools/ci/check_article_details.sh | 37 +++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/tools/ci/check_article_details.sh b/tools/ci/check_article_details.sh index ef366cd50..cda3776bb 100644 --- a/tools/ci/check_article_details.sh +++ b/tools/ci/check_article_details.sh @@ -467,6 +467,42 @@ validate_added_articles() { return 1 } +find_trailing_spaces() { + echo + echo "Looking for trailing whitespaces..." + + local job_error=0 + + while IFS= read -r file; do + # Skip empty lines + [[ -z "$file" ]] && continue + + # Check if file exists + if [[ ! -f "$file" ]]; then + echo "Warning: File not found: $file" + continue + fi + + # Count lines with trailing spaces + count=$(grep -c '[[:blank:]]$' "$file") + + # Report only if there are trailing spaces + if [[ "$count" -gt 0 ]] 2>/dev/null; then + job_error=1 + echo + echo "❌ Lines end with extra spaces or tabs." + echo " Remove trailing whitespaces from (use
where needed):" + echo " $file -- $count line(s) in total." + fi + done < "$TEMP_DIR/index-added.txt" + + if [ "$job_error" -eq 0 ]; then + return 0 + fi + + return 1 +} + ############################################################################### # FEATURE ASSET VALIDATION @@ -782,6 +818,7 @@ banner "🔎 Checking added files..." if [[ -s "$TEMP_DIR/index-added.txt" ]]; then extract_added_metadata || overall_error=1 validate_added_articles || overall_error=1 + find_trailing_spaces || overall_error=1 validate_author_presence || overall_error=1 validate_feature_assets || overall_error=1 else