Skip to content

Sync Next.js Official Documentation #11

Sync Next.js Official Documentation

Sync Next.js Official Documentation #11

Workflow file for this run

name: Sync Next.js Official 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:
check-branch:
name: Check if PR branch exists
runs-on: ubuntu-latest
outputs:
should_sync: ${{ steps.check_branch.outputs.should_sync }}
steps:
- name: Check if PR branch exists
id: check_branch
run: |
if git ls-remote --heads https://github.com/${{ github.repository }}.git | grep -q "docs/sync-nextjs-documentation"; then
echo "Branch already exists, skipping update"
echo "should_sync=false" >> $GITHUB_OUTPUT
else
echo "Branch does not exist, proceeding with update"
echo "should_sync=true" >> $GITHUB_OUTPUT
fi
sync-docs:
name: Sync Next.js Docs
runs-on: ubuntu-latest
needs: check-branch
if: needs.check-branch.outputs.should_sync == 'true'
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Clone Next.js repository (canary)
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)
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)
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: Setup Tools
uses: ./.github/actions/setup
- name: Sync blog & learn
run: |
node packages/crawler/dist/index.js
- name: Find available translation locales
id: find_locales
run: |
cd apps/docs/content
LOCALES=$(find . -maxdepth 1 -type d | grep -v "^.$" | grep -v "/en$" | sed 's|^\./||' | tr '\n' ' ' | sed 's/ $//')
echo "Available translation locales: $LOCALES"
echo "locales=$LOCALES" >> $GITHUB_OUTPUT
- name: Stage changes to detect renames
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
run: |
# Get list of renamed files from git status
RENAMES=$(git status --porcelain | grep -E "^R[[:space:]]+apps/docs/content/en" | sed 's/^R[[:space:]]*//')
# Get list of deleted files from git status
DELETES=$(git status --porcelain | grep -E "^D[[:space:]]+apps/docs/content/en" | 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
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_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`
- Updates from blog to `apps/docs/content/en/blog`
- Updates from learn to `apps/docs/content/en/learn`
branch: docs/sync-nextjs-documentation
delete-branch: true
base: dev
add-paths: |
apps/docs/content/