diff --git a/.github/workflows/preview-pr.yml b/.github/workflows/preview-pr.yml index 7ac1b683ec..356ff5a035 100644 --- a/.github/workflows/preview-pr.yml +++ b/.github/workflows/preview-pr.yml @@ -1,71 +1,26 @@ name: PR Preview on: + push: + branches: + - preview/** + - preview-cloud/** + - preview-operator/** workflow_dispatch: - inputs: - PR_REPO: - required: true - type: choice - options: ['pingcap/docs', 'pingcap/docs-cn'] - default: 'pingcap/docs' - description: 'The repository to preview' - PR_NUMBER: - required: true - type: number - description: 'The PR number to preview' - PREVIEW_PRODUCT: - required: true - type: choice - options: ["tidb", "tidbcloud"] - default: "tidb" - description: 'The product to preview' - PREVIEW_BRANCH: - required: true - type: string - default: 'master' - description: 'The branch to preview, such as master, release-x.y' jobs: - copy_files: + sync: runs-on: ubuntu-latest steps: - name: Check out destination repository uses: actions/checkout@v3 - with: - path: pingcap-docs-website-scaffold - - name: Check out source repository - uses: actions/checkout@v3 - with: - repository: ${{ github.event.inputs.PR_REPO }} - path: source-repo - - - name: Copy files + - name: Sync PR run: | - chmod +x pingcap-docs-website-scaffold/sync_pr.sh - - if [ "${{ github.event.inputs.PR_REPO }}" = "pingcap/docs" ] - then - export LANG="en" - elif [ "${{ github.event.inputs.PR_REPO }}" = "pingcap/docs-cn" ] - then - export LANG="zh" - fi - - pingcap-docs-website-scaffold/sync_pr.sh ${{ github.event.inputs.PR_NUMBER }} source-repo pingcap-docs-website-scaffold/markdown-pages/$LANG/${{ github.event.inputs.PREVIEW_PRODUCT }}/${{ github.event.inputs.PREVIEW_BRANCH }} - - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Commit and push changes - run: | - cd source-repo - LAST_COMMIT=$(git rev-parse HEAD) - cd ../pingcap-docs-website-scaffold - git status git config user.name github-actions git config user.email github-actions@github.com - git add -A - git commit -m "Update files from https://github.com/${{ github.event.inputs.PR_REPO }}/pull/${{ github.event.inputs.PR_NUMBER }}/commits/$LAST_COMMIT" || echo "No changes to commit" + ./sync.sh git push + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index 38af278149..9d197a3cc9 100644 --- a/.gitignore +++ b/.gitignore @@ -142,4 +142,6 @@ dist .svelte-kit website-docs -# End of https://www.toptal.com/developers/gitignore/api/node \ No newline at end of file +# End of https://www.toptal.com/developers/gitignore/api/node + +src/ diff --git a/build.sh b/build.sh index 28dfe30383..01770aced9 100755 --- a/build.sh +++ b/build.sh @@ -2,58 +2,81 @@ set -e +# Get the directory of this script +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) + +cd "$SCRIPT_DIR" + +# Select appropriate versions of find and sed depending on OS. FIND=$(which gfind || which find) SED=$(which gsed || which sed) +# This function replaces the image paths in markdown files. replace_image_path() { -( cd markdown-pages - $FIND . -maxdepth 3 -mindepth 3 | while IFS= read -r DIR; do - DIR="${DIR#./}" - PREFIX="$(dirname "$DIR")" - $FIND "$DIR" -name '*.md' | while IFS= read -r FILE; do - $SED -r -i "s~]\(/media(/$PREFIX)?~](/media/$PREFIX~g" "$FILE" + ( cd markdown-pages + $FIND . -maxdepth 3 -mindepth 3 | while IFS= read -r DIR; do + DIR="${DIR#./}" + PREFIX="$(dirname "$DIR")" + # Find all markdown files. + $FIND "$DIR" -name '*.md' | while IFS= read -r FILE; do + # Replace the image paths in the markdown files. + $SED -r -i "s~]\(/media(/$PREFIX)?~](/media/$PREFIX~g" "$FILE" + done done - done -) - + ) } +# This function moves image files to another location. move_images() { -( cd markdown-pages - $FIND . -maxdepth 3 -mindepth 3 | while IFS= read -r DIR; do - PREFIX="$(dirname "$DIR")" - if [ -d "$PREFIX/master/media" ]; then - mkdir -p "../website-docs/public/media/$PREFIX" - cp -r "$PREFIX/master/media/." "../website-docs/public/media/$PREFIX" - fi - done -) - + ( cd markdown-pages + $FIND . -maxdepth 3 -mindepth 3 | while IFS= read -r DIR; do + PREFIX="$(dirname "$DIR")" + # Check if the media directory exists. + if [ -d "$PREFIX/master/media" ]; then + # Create the target directory. + mkdir -p "../website-docs/public/media/$PREFIX" + # Copy the image files to the target directory. + cp -r "$PREFIX/master/media/." "../website-docs/public/media/$PREFIX" + fi + done + ) } +# The default command is build, which builds the website for production. CMD=build +# If the argument is develop or dev, change the command to start, which builds the website for development. if [ "$1" == "develop" ] || [ "$1" == "dev" ]; then CMD=start fi if [ ! -e website-docs/.git ]; then + if [ -d "website-docs" ]; then + rm -rf website-docs + fi + # Clone the pingcap/website-docs repository. git clone https://github.com/pingcap/website-docs fi +# Check if the symlink doesn't exist. if [ ! -e website-docs/docs/markdown-pages ]; then + # Create a symlink to markdown-pages in website-docs/docs. ln -s ../../markdown-pages website-docs/docs/markdown-pages fi +# Copy docs.json to website-docs/docs. cp docs.json website-docs/docs/docs.json +# Run the start command. if [ "$CMD" == "start" ]; then (cd website-docs && yarn && yarn start) fi +# Run the build command. /dev/null && pwd ) +cd "$SCRIPT_DIR" + +# Verify if jq is installed and GITHUB_TOKEN is set. +which jq &> /dev/null || (echo "Error: jq is not installed, but is required for this script to parse JSON response from GitHub API. You can download and install jq from https://stedolan.github.io/jq/download/" && exit 1) +test -n "$GITHUB_TOKEN" || (echo "Error: The GITHUB_TOKEN environment variable is not set. This token is required for accessing the GitHub API and needs to have the repo scope." && exit 1) + +# If the branch name is not provided as an argument, use the current branch. +BRANCH_NAME=${1:-$(git branch --show-current)} + +# Extract product, repo owner, repo name, and PR number from the branch name. The name pattern is r"preview(-cloud|-operator)?/pingcap/docs(-cn|-tidb-operator)?/[0-9]+)" +PREVIEW_PRODUCT=$(echo "$BRANCH_NAME" | cut -d'/' -f1) +REPO_OWNER=$(echo "$BRANCH_NAME" | cut -d'/' -f2) +REPO_NAME=$(echo "$BRANCH_NAME" | cut -d'/' -f3) +PR_NUMBER=$(echo "$BRANCH_NAME" | cut -d'/' -f4) + +# Get the base branch of this PR +BASE_BRANCH=$(curl -fsSL -H "Authorization: token $GITHUB_TOKEN" \ + "https://api.github.com/repos/$REPO_OWNER/$REPO_NAME/pulls/$PR_NUMBER" | \ + jq -r '.base.ref') + +# Ensure that BASE_BRANCH is not empty +test -n "$BASE_BRANCH" || (echo "Error: Cannot get BASE_BRANCH." && exit 1) + +# Determine product name based on the PREVIEW_PRODUCT +case "$PREVIEW_PRODUCT" in + preview) + DIR_SUFFIX="tidb/${BASE_BRANCH}" + ;; + preview-cloud) + DIR_SUFFIX="tidbcloud/master" + ;; + preview-operator) + DIR_SUFFIX="tidb-in-kubernetes/${BASE_BRANCH}" + ;; + *) + echo "Error: Branch name must start with preview/, preview-cloud/, or preview-operator/." + exit 1 + ;; +esac + +# Define sync tasks for different repos +case "$REPO_NAME" in + docs) + # sync all modified or added files from root dir to markdown-pages/en/ + SYNC_TASKS=("./,en/") + ;; + docs-cn) + # sync all modified or added files from root dir to markdown-pages/zh/ + SYNC_TASKS=("./,zh/") + ;; + docs-tidb-operator) + # Task 1: sync all modified or added files from en/ to markdown-pages/en/ + # Task 2: sync all modified or added files from zh/ to markdown-pages/zh/ + SYNC_TASKS=("en/,en/" "zh/,zh/") + ;; + *) + echo "Error: Invalid repo name. Only docs, docs-cn, and docs-tidb-operator are supported." + exit 1 + ;; +esac + +REPO_DIR="src/$REPO_NAME" + +# Clone repo if it doesn't exist already +test -e "$REPO_DIR/.git" || git clone "https://github.com/$REPO_OWNER/$REPO_NAME.git" "$REPO_DIR" + +# --update-head-ok: By default git fetch refuses to update the head which corresponds to the current branch. This flag disables the check. This is purely for the internal use for git pull to communicate with git fetch, and unless you are implementing your own Porcelain you are not supposed to use it. +# use --force to overwrite local branch when remote branch is force pushed +git -C "$REPO_DIR" fetch origin "$BASE_BRANCH" # +git -C "$REPO_DIR" fetch origin pull/"$PR_NUMBER"/head:PR-"$PR_NUMBER" --update-head-ok --force +git -C "$REPO_DIR" checkout PR-"$PR_NUMBER" + +# Perform sync tasks +for TASK in "${SYNC_TASKS[@]}"; do + + SRC_DIR=$(echo "$TASK" | cut -d',' -f1) + DEST_DIR="markdown-pages/$(echo "$TASK" | cut -d',' -f2)/$DIR_SUFFIX" + mkdir -p "$DEST_DIR" + # Only sync modified or added files + git -C "$REPO_DIR" diff --merge-base --name-only --diff-filter=AM origin/"$BASE_BRANCH" "$SRC_DIR" | tee /dev/fd/2 | \ + rsync -av --files-from=- "$REPO_DIR" "$DEST_DIR" + +done + +test -n "$TEST" && echo "Test mode, exiting..." && exit 0 + +# Get the current commit SHA +CURRENT_COMMIT=$(git -C "$REPO_DIR" rev-parse HEAD) + +# Handle untracked files +git add . +# Commit changes, if any +git commit -m "Preview PR https://github.com/$REPO_OWNER/$REPO_NAME/pull/$PR_NUMBER and this preview is triggered from commit https://github.com/$REPO_OWNER/$REPO_NAME/pull/$PR_NUMBER/commits/$CURRENT_COMMIT" || echo "No changes to commit" diff --git a/sync_pr.sh b/sync_pr.sh deleted file mode 100755 index 828a45bc47..0000000000 --- a/sync_pr.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/bash - -set -e - -# Check if the right number of arguments were passed -if [ "$#" -ne 3 ]; then - echo "Usage: $0 PR_NUMBER SRC_DIR DEST_DIR" - exit 1 -fi - -PR_NUMBER=$1 -SRC_DIR=$2 -DEST_DIR=$3 - -WORKSPACE=$(pwd) - -# Check if source directory exists -if [ ! -d "$WORKSPACE/$SRC_DIR" ]; then - echo "Error: Source directory $WORKSPACE/$SRC_DIR does not exist." - exit 1 -fi - - -cd "$WORKSPACE/$SRC_DIR" -gh pr checkout "$PR_NUMBER" -LAST_COMMIT=$(git rev-parse HEAD) -echo "The last commit is: $LAST_COMMIT" -gh pr diff "$PR_NUMBER" --name-only > pr_diff.txt - - -while read -r FILE; do - echo "Processing $FILE" - if [ -f "$WORKSPACE/$SRC_DIR/$FILE" ]; then - # Ensure destination directory exists - mkdir -p "$WORKSPACE/$DEST_DIR/$(dirname "$FILE")" - - # Use rsync to copy each FILE to the destination directory - rsync -av "$WORKSPACE/$SRC_DIR/$FILE" "$WORKSPACE/$DEST_DIR/$FILE" - fi -done < "$WORKSPACE/$SRC_DIR/pr_diff.txt"