Skip to content

Update Next.js English Documentation #5

Update Next.js English Documentation

Update Next.js English Documentation #5

name: Update Next.js English Documentation
on:
workflow_dispatch: # Manual trigger
schedule:
# 8 AM Los Angeles (Pacific) time - corresponds to UTC-7 (PDT) or UTC-8 (PST)
# This cron format is in UTC, so 15:00 UTC during PDT, 16:00 UTC during PST
- cron: "0 15 * * *"
# Add permissions needed for creating PRs
permissions:
contents: write
pull-requests: write
jobs:
update-docs:
name: Update Next.js Docs
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Check if PR branch exists
id: check_branch
run: |
if git ls-remote --heads origin "docs-update-nextjs-documentation" | grep -q "docs-update-nextjs-documentation"; then
echo "Branch already exists, skipping update"
echo "branch_exists=true" >> $GITHUB_OUTPUT
else
echo "Branch does not exist, proceeding with update"
echo "branch_exists=false" >> $GITHUB_OUTPUT
fi
- name: Clone Next.js repository (canary)
if: steps.check_branch.outputs.branch_exists == 'false'
run: |
git clone --depth 1 --branch canary --single-branch https://github.com/vercel/next.js.git nextjs-canary
mkdir -p apps/docs/content/en/docs
rsync -av --delete nextjs-canary/docs/ apps/docs/content/en/docs/ --exclude="13" --exclude="14"
rm -rf nextjs-canary
- name: Clone Next.js repository (v14.2.28)
if: steps.check_branch.outputs.branch_exists == 'false'
run: |
git clone --depth 1 --branch v14.2.28 --single-branch https://github.com/vercel/next.js.git nextjs-v14
mkdir -p apps/docs/content/en/docs/14
rsync -av --delete nextjs-v14/docs/ apps/docs/content/en/docs/14/
rm -rf nextjs-v14
- name: Clone Next.js repository (v13.5.11)
if: steps.check_branch.outputs.branch_exists == 'false'
run: |
git clone --depth 1 --branch v13.5.11 --single-branch https://github.com/vercel/next.js.git nextjs-v13
mkdir -p apps/docs/content/en/docs/13
rsync -av --delete nextjs-v13/docs/ apps/docs/content/en/docs/13/
rm -rf nextjs-v13
- name: Find available translation locales
if: steps.check_branch.outputs.branch_exists == 'false'
id: find_locales
run: |
cd apps/docs/content
LOCALES=$(find . -maxdepth 1 -type d | grep -v "^.$" | grep -v "/en$" | sed 's|^\./||')
echo "Available translation locales: $LOCALES"
echo "locales=$LOCALES" >> $GITHUB_OUTPUT
- name: Stage changes to detect renames
if: steps.check_branch.outputs.branch_exists == 'false'
run: |
# Stage all changes so Git can detect renames
git add .
# Show what Git sees after staging
echo "Git status after staging:"
git status --porcelain
- name: Process file renames and deletions
if: steps.check_branch.outputs.branch_exists == 'false'
run: |
# Get list of renamed files from git status
RENAMES=$(git status --porcelain | grep -E "^R[[:space:]]+apps/docs/content/en/docs" | sed 's/^R[[:space:]]*//')
# Get list of deleted files from git status
DELETES=$(git status --porcelain | grep -E "^D[[:space:]]+apps/docs/content/en/docs" | sed 's/^D[[:space:]]*//')
# Generate current timestamp in ISO format
CURRENT_TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%S.000Z")
echo "Current timestamp: $CURRENT_TIMESTAMP"
# Process renames
if [ -n "$RENAMES" ]; then
echo "File renames detected in English docs. Processing for other languages..."
# For each locale
for LOCALE in ${{ steps.find_locales.outputs.locales }}; do
echo "Processing renames for locale: $LOCALE"
# For each renamed file
echo "$RENAMES" | while read -r LINE; do
# Split the line into source and destination
# After sed processing, each LINE is in format: "oldname -> newname"
SOURCE=$(echo "$LINE" | awk -F ' -> ' '{print $1}')
DEST=$(echo "$LINE" | awk -F ' -> ' '{print $2}')
# Check if there are actual content changes using git diff with -M (detect renames)
# If there's output from the diff command beyond the rename header, there are content changes
DIFF_OUTPUT=$(git diff --cached -M -- "$SOURCE" "$DEST")
# Count lines that start with +/- (changes) but ignore the rename header lines
CHANGE_COUNT=$(echo "$DIFF_OUTPUT" | grep -v "^renamed:" | grep -v "^─" | grep -E "^\+|^-" | wc -l)
echo "Git diff for '$SOURCE' → '$DEST': $CHANGE_COUNT lines changed"
# Determine if this is just a rename or if content was also changed
if [ "$CHANGE_COUNT" -eq 0 ]; then
CONTENT_UNCHANGED=true
echo "Pure rename detected (no content changes)"
else
CONTENT_UNCHANGED=false
echo "Content changes detected along with rename"
fi
# Replace 'en' with current locale in paths
SOURCE_LOCALE=${SOURCE/content\/en/content\/$LOCALE}
DEST_LOCALE=${DEST/content\/en/content\/$LOCALE}
# Check if source file exists in this locale
if [ -f "$SOURCE_LOCALE" ]; then
echo "Renaming $SOURCE_LOCALE to $DEST_LOCALE"
# Create directory if it doesn't exist
mkdir -p $(dirname "$DEST_LOCALE")
# Move the file
mv "$SOURCE_LOCALE" "$DEST_LOCALE"
# If the content is identical (just a rename, not a modification)
# then update the timestamps in the translation file
if [ "$CONTENT_UNCHANGED" = "true" ]; then
echo "Content unchanged, updating timestamps in $DEST_LOCALE"
# Update source-updated-at and translation-updated-at in the file
# Using portable sed syntax that works on both Linux and macOS
perl -i -pe "s/source-updated-at: .*/source-updated-at: '$CURRENT_TIMESTAMP'/" "$DEST_LOCALE"
perl -i -pe "s/translation-updated-at: .*/translation-updated-at: '$CURRENT_TIMESTAMP'/" "$DEST_LOCALE"
else
echo "Content changed, keeping original timestamps for translation to detect changes"
fi
fi
done
done
else
echo "No file renames detected in English docs."
fi
# Process deletions
if [ -n "$DELETES" ]; then
echo "File deletions detected in English docs. Processing for other languages..."
# For each locale
for LOCALE in ${{ steps.find_locales.outputs.locales }}; do
echo "Processing deletions for locale: $LOCALE"
# For each deleted file
echo "$DELETES" | while read -r FILE; do
# Replace 'en' with current locale in paths
FILE_LOCALE=${FILE/content\/en/content\/$LOCALE}
# Check if file exists in this locale
if [ -f "$FILE_LOCALE" ]; then
echo "Deleting $FILE_LOCALE"
rm -f "$FILE_LOCALE"
# Check if parent directory is empty and remove it if it is
DIR=$(dirname "$FILE_LOCALE")
if [ -d "$DIR" ] && [ -z "$(ls -A $DIR)" ]; then
echo "Removing empty directory: $DIR"
rmdir "$DIR"
fi
fi
done
done
else
echo "No file deletions detected in English docs."
fi
- name: Check for modifications
if: steps.check_branch.outputs.branch_exists == 'false'
id: check_changes
run: |
if [[ $(git status --porcelain | grep -E "apps/docs/content/" | wc -l) -gt 0 ]]; then
echo "has_changes=true" >> $GITHUB_OUTPUT
echo "Changes detected. Will proceed with PR."
else
echo "has_changes=false" >> $GITHUB_OUTPUT
echo "No changes detected in docs. Skipping PR."
fi
- name: Create Pull Request
if: steps.check_branch.outputs.branch_exists == 'false' && steps.check_changes.outputs.has_changes == 'true'
uses: peter-evans/create-pull-request@v5
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: "docs: update nextjs documentation"
title: "docs: update nextjs documentation"
body: |
This PR updates the Next.js English documentation from the official Next.js repository.
- Updates from `canary` branch to `apps/docs/content/en/docs`
- Updates from `v14.2.28` branch to `apps/docs/content/en/docs/14`
- Updates from `v13.5.11` branch to `apps/docs/content/en/docs/13`
branch: docs-update-nextjs-documentation
delete-branch: true
base: main
add-paths: |
apps/docs/content/