Skip to content

Add Node.js WebSocket server example #1553

Add Node.js WebSocket server example

Add Node.js WebSocket server example #1553

name: Ensure nav is updated if files added/deleted
permissions: {}
on:
pull_request:
types: [opened, synchronize, reopened]
jobs:
is-nav-updated:
permissions:
contents: read
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
- name: Get added and deleted .mdx files
id: mdx-files
run: |
git fetch origin ${{ github.base_ref }}
# Write lists to files so the next step never interpolates untrusted data into the script (code-injection safe)
added_files=""
deleted_files=""
while IFS= read -r file; do
[ -z "$file" ] && continue
[[ "$file" == *.mdx ]] || continue
[[ "$file" == snippets/* ]] && continue
[[ "$file" == api-reference/* ]] && continue
[[ "$file" == custom/* ]] && continue
[[ "$file" == errors/* ]] && continue
# Reject paths that could break shell when used later
if [[ "$file" =~ [\"\\] ]]; then
echo "::error file=$file::Path contains invalid characters"
exit 1
fi
added_files+="$file"$'\n'
done < <(git diff --name-only --diff-filter=A origin/${{ github.base_ref }}...HEAD)
while IFS= read -r file; do
[ -z "$file" ] && continue
[[ "$file" == *.mdx ]] || continue
[[ "$file" == snippets/* ]] && continue
[[ "$file" == api-reference/* ]] && continue
[[ "$file" == custom/* ]] && continue
[[ "$file" == errors/* ]] && continue
if [[ "$file" =~ [\"\\] ]]; then
echo "::error file=$file::Path contains invalid characters"
exit 1
fi
deleted_files+="$file"$'\n'
done < <(git diff --name-only --diff-filter=D origin/${{ github.base_ref }}...HEAD)
printf '%s' "$added_files" > added_files.txt
printf '%s' "$deleted_files" > deleted_files.txt
echo "added_count=$(printf '%s' "$added_files" | grep -c . || true)" >> $GITHUB_OUTPUT
echo "deleted_count=$(printf '%s' "$deleted_files" | grep -c . || true)" >> $GITHUB_OUTPUT
- name: Check docs.json updated
run: |
# Read from files written by previous step (no untrusted data in workflow interpolation)
added_files="$(cat added_files.txt)"
deleted_files="$(cat deleted_files.txt)"
if [ -z "$added_files" ] && [ -z "$deleted_files" ]; then
echo "No .mdx files were added or deleted in this PR."
exit 0
fi
echo "Checking if the files you added have noSidebar: true in the frontmatter."
filtered_added_files=()
while IFS= read -r file; do
if [ -z "$file" ]; then
continue
fi
if git show HEAD:"$file" 2>/dev/null | grep -qE "^noSidebar:\s*true"; then
echo "⊘ Ignoring $file (has noSidebar: true)"
else
filtered_added_files+=("$file")
fi
done < added_files.txt
if [ ${#filtered_added_files[@]} -eq 0 ] && [ -z "$deleted_files" ]; then
echo "No .mdx files require navigation updates (all added files have noSidebar: true)."
exit 0
fi
git fetch origin ${{ github.base_ref }}
docs_json_changed=false
if git diff --name-only origin/${{ github.base_ref }}...HEAD | grep -q '^docs.json$'; then
docs_json_changed=true
fi
if [ "$docs_json_changed" = false ]; then
navigation_string=$(jq -c '.navigation' docs.json)
files_in_nav_but_not_updated=()
while IFS= read -r file; do
if [ -z "$file" ]; then
continue
fi
path_without_ext="${file%.mdx}"
if echo "$navigation_string" | grep -q "$path_without_ext"; then
echo "::error file=$file::Deleted file exists in navigation but docs.json was not updated: $file"
files_in_nav_but_not_updated+=("$file")
else
echo "⊘ Deleted file was never in navigation, skipping: $file"
fi
done < deleted_files.txt
if [ ${#filtered_added_files[@]} -gt 0 ] || [ ${#files_in_nav_but_not_updated[@]} -gt 0 ]; then
echo "::error file=docs.json::docs.json was not updated, but .mdx files were added or deleted."
echo ""
echo "❌ The navigation array in docs.json must be updated when adding or deleting .mdx files. If you're creating a page that you don't want in the sidebar, add noSidebar: true to the frontmatter."
exit 1
else
echo "✓ All deleted files were never in navigation. No docs.json update required."
exit 0
fi
fi
echo "docs.json was modified. Checking navigation array..."
navigation_string=$(jq -c '.navigation' docs.json)
missing_paths=()
for file in "${filtered_added_files[@]}"; do
path_without_ext="${file%.mdx}"
echo "Checking if added file is in navigation: $path_without_ext"
if echo "$navigation_string" | grep -q "$path_without_ext"; then
echo "✓ Found in navigation: $file"
else
echo "::error file=$file::Added file not found in docs.json navigation: $file (expected: $path_without_ext)"
missing_paths+=("+ $file → $path_without_ext")
fi
done
while IFS= read -r file; do
if [ -z "$file" ]; then
continue
fi
path_without_ext="${file%.mdx}"
echo "Checking if deleted file is removed from navigation: $path_without_ext"
if echo "$navigation_string" | grep -q "$path_without_ext"; then
echo "::error file=$file::Deleted file still exists in docs.json navigation: $file (path: $path_without_ext)"
missing_paths+=("- $file → $path_without_ext")
else
echo "✓ Removed from navigation: $file"
fi
done < deleted_files.txt
if [ ${#missing_paths[@]} -gt 0 ]; then
echo ""
echo "❌ The following file changes are not reflected in docs.json:"
printf ' %s\n' "${missing_paths[@]}"
echo ""
echo "Please update docs.json to include these file paths."
exit 1
else
echo ""
echo "✓ All .mdx file changes are properly reflected in docs.json."
fi