|
| 1 | +#!/usr/bin/env bash |
| 2 | +# |
| 3 | +# Track changes in php/doc-en and create issues in doc-zh |
| 4 | +# for files that need translation updates. |
| 5 | +# |
| 6 | +# How it works: |
| 7 | +# - Fetches all commits on doc-en master from the last 7 days |
| 8 | +# - For each commit, checks if a matching issue already exists in doc-zh |
| 9 | +# - If not, creates one listing the ZH files to update |
| 10 | +# |
| 11 | +# Why iterate commits instead of merged PRs: maintainers sometimes push |
| 12 | +# directly to master without going through a PR (e.g. cherry-picking a |
| 13 | +# contributor's patch). Those changes are real translation work but the |
| 14 | +# PR-based tracker misses them. Walking the commit log catches both cases. |
| 15 | +# |
| 16 | +# Why 7 days: the action runs daily, so 7 days gives us 6 days of margin. |
| 17 | +# Even if the action fails for a whole week, nothing is missed. |
| 18 | +# Duplicates are prevented by searching for the commit SHA (or associated PR |
| 19 | +# number for backward compat) in existing issue titles/bodies. |
| 20 | +# |
| 21 | +set -euo pipefail |
| 22 | + |
| 23 | +# Ensure the sync-en label exists (idempotent) |
| 24 | +gh label create "sync-en" --color "#0075ca" --description "Track EN changes" \ |
| 25 | + --repo "$GH_REPO" 2>/dev/null || true |
| 26 | + |
| 27 | +SINCE=$(date -u -d '7 days ago' '+%Y-%m-%dT%H:%M:%SZ') |
| 28 | +echo "Checking doc-en commits on master since $SINCE" |
| 29 | + |
| 30 | +# Fetch all commits on master from the last 7 days (paginate if needed) |
| 31 | +PAGE=1 |
| 32 | +ALL_SHAS="" |
| 33 | +while :; do |
| 34 | + BATCH=$(gh api "repos/php/doc-en/commits?sha=master&since=$SINCE&per_page=100&page=$PAGE" \ |
| 35 | + --jq '.[].sha' 2>/dev/null || true) |
| 36 | + COUNT=$(echo "$BATCH" | grep -c . 2>/dev/null || echo "0") |
| 37 | + if [ -n "$BATCH" ]; then |
| 38 | + ALL_SHAS="$ALL_SHAS"$'\n'"$BATCH" |
| 39 | + fi |
| 40 | + echo " Page $PAGE: $COUNT commit(s)" |
| 41 | + if [ "$COUNT" -lt 100 ]; then |
| 42 | + break |
| 43 | + fi |
| 44 | + PAGE=$((PAGE + 1)) |
| 45 | +done |
| 46 | + |
| 47 | +echo "$ALL_SHAS" | sed '/^$/d' > /tmp/commits.txt |
| 48 | +TOTAL=$(wc -l < /tmp/commits.txt) |
| 49 | +echo "Total: $TOTAL commit(s) on master in the last 7 days" |
| 50 | + |
| 51 | +if [ "$TOTAL" -eq 0 ]; then |
| 52 | + echo "Nothing to do." |
| 53 | + exit 0 |
| 54 | +fi |
| 55 | + |
| 56 | +CREATED=0 |
| 57 | +SKIPPED=0 |
| 58 | + |
| 59 | +while read -r SHA; do |
| 60 | + [ -z "$SHA" ] && continue |
| 61 | + |
| 62 | + SHORT_SHA=${SHA:0:7} |
| 63 | + |
| 64 | + # Get commit info (single API call) |
| 65 | + COMMIT_DATA=$(gh api "repos/php/doc-en/commits/$SHA" \ |
| 66 | + --jq '{msg: (.commit.message | split("\n")[0]), date: .commit.author.date, author: (.author.login // .commit.author.name), files: [.files[].filename]}' 2>/dev/null) |
| 67 | + COMMIT_MSG=$(echo "$COMMIT_DATA" | jq -r '.msg') |
| 68 | + COMMIT_DATE=$(echo "$COMMIT_DATA" | jq -r '.date' | cut -dT -f1) |
| 69 | + COMMIT_AUTHOR=$(echo "$COMMIT_DATA" | jq -r '.author') |
| 70 | + |
| 71 | + echo "" |
| 72 | + echo "Commit $SHORT_SHA by $COMMIT_AUTHOR: $COMMIT_MSG" |
| 73 | + |
| 74 | + # Skip commits marked with [skip-revcheck] |
| 75 | + if echo "$COMMIT_MSG" | grep -qi '\[skip-revcheck\]'; then |
| 76 | + echo " -> [skip-revcheck], skipping." |
| 77 | + SKIPPED=$((SKIPPED + 1)) |
| 78 | + continue |
| 79 | + fi |
| 80 | + |
| 81 | + # Deduplication: search for the full commit SHA in existing issues |
| 82 | + EXISTING=$(gh issue list --repo "$GH_REPO" --search "\"$SHA\"" \ |
| 83 | + --state all --json number --jq 'length') |
| 84 | + if [ "$EXISTING" -gt 0 ]; then |
| 85 | + echo " -> Issue already exists (by SHA), skipping." |
| 86 | + SKIPPED=$((SKIPPED + 1)) |
| 87 | + continue |
| 88 | + fi |
| 89 | + |
| 90 | + # Backward compat: if commit is associated with a PR, also check by PR number |
| 91 | + PR_NUMBER=$(gh api "repos/php/doc-en/commits/$SHA/pulls" \ |
| 92 | + --jq '.[0].number // empty' 2>/dev/null || true) |
| 93 | + if [ -n "$PR_NUMBER" ]; then |
| 94 | + EXISTING=$(gh issue list --repo "$GH_REPO" --search "\"doc-en/pull/$PR_NUMBER\"" \ |
| 95 | + --state all --json number --jq 'length') |
| 96 | + if [ "$EXISTING" -gt 0 ]; then |
| 97 | + echo " -> Issue already exists (by PR #$PR_NUMBER), skipping." |
| 98 | + SKIPPED=$((SKIPPED + 1)) |
| 99 | + continue |
| 100 | + fi |
| 101 | + fi |
| 102 | + |
| 103 | + # Get files changed in this commit |
| 104 | + FILES=$(echo "$COMMIT_DATA" | jq -r '.files[]') |
| 105 | + |
| 106 | + if [ -z "$FILES" ]; then |
| 107 | + echo " -> No files found, skipping." |
| 108 | + continue |
| 109 | + fi |
| 110 | + |
| 111 | + # Categorize files |
| 112 | + UPDATE_LIST="" |
| 113 | + NEW_LIST="" |
| 114 | + |
| 115 | + while IFS= read -r FILE; do |
| 116 | + if [[ "$FILE" == */versions.xml ]]; then |
| 117 | + continue |
| 118 | + fi |
| 119 | + if [ -f "$FILE" ]; then |
| 120 | + UPDATE_LIST="${UPDATE_LIST}- \`${FILE}\`"$'\n' |
| 121 | + elif [[ "$FILE" == *.xml ]]; then |
| 122 | + NEW_LIST="${NEW_LIST}- \`${FILE}\`"$'\n' |
| 123 | + fi |
| 124 | + done <<< "$FILES" |
| 125 | + |
| 126 | + # Skip if no ES-relevant files |
| 127 | + if [ -z "$UPDATE_LIST" ] && [ -z "$NEW_LIST" ]; then |
| 128 | + echo " -> No ZH-relevant files, skipping." |
| 129 | + continue |
| 130 | + fi |
| 131 | + |
| 132 | + # Build issue body (URLs in backticks to avoid crosslinks) |
| 133 | + BODY="Commit: \`https://github.com/php/doc-en/commit/$SHA\`"$'\n' |
| 134 | + if [ -n "$PR_NUMBER" ]; then |
| 135 | + BODY+="PR: \`https://github.com/php/doc-en/pull/$PR_NUMBER\`"$'\n' |
| 136 | + fi |
| 137 | + |
| 138 | + if [ -n "$UPDATE_LIST" ]; then |
| 139 | + BODY+=$'\n'"**Archivos ZH files to update**"$'\n' |
| 140 | + BODY+="$UPDATE_LIST" |
| 141 | + fi |
| 142 | + |
| 143 | + if [ -n "$NEW_LIST" ]; then |
| 144 | + BODY+=$'\n'"**New EN files (not yet translated)**"$'\n' |
| 145 | + BODY+="$NEW_LIST" |
| 146 | + fi |
| 147 | + |
| 148 | + # Create the issue |
| 149 | + ISSUE_TITLE="[Sync EN] $COMMIT_MSG" |
| 150 | + echo "$BODY" | gh issue create \ |
| 151 | + --repo "$GH_REPO" \ |
| 152 | + --title "$ISSUE_TITLE" \ |
| 153 | + --label "sync-en" \ |
| 154 | + --body-file - |
| 155 | + |
| 156 | + echo " -> Issue created." |
| 157 | + CREATED=$((CREATED + 1)) |
| 158 | +done < /tmp/commits.txt |
| 159 | + |
| 160 | +echo "" |
| 161 | +echo "Done. Created: $CREATED, Skipped: $SKIPPED" |
0 commit comments