Update origin-src for Translation #276
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Update origin-src for Translation | |
| on: | |
| workflow_dispatch: | |
| schedule: | |
| - cron: "0 0 * * *" | |
| jobs: | |
| update-origin-src: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| issues: write | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v3 | |
| with: | |
| fetch-depth: 0 | |
| - name: Set git identity | |
| shell: bash | |
| run: | | |
| set -Eeuo pipefail | |
| git config --global user.name "minchodang" | |
| git config --global user.email "[email protected]" | |
| - name: Extract src from origin/master | |
| shell: bash | |
| run: | | |
| set -Eeuo pipefail | |
| WORK=$(mktemp -d) | |
| git archive origin/master src | tar -x -C "$WORK" | |
| mv "$WORK/src" master-src | |
| # โ ์ฒดํฌ์ฌ ๊ธฐ๋ฐ ๋ณ๊ฒฝ ํ์ง (ADD / MODIFY / DELETE ์ ํ ๋ถ๋ฅ) | |
| - name: Detect changes between origin-src and master-src | |
| id: compare | |
| shell: bash | |
| run: | | |
| set -Eeuo pipefail | |
| mkdir -p origin-src | |
| ( cd master-src && find . -type f -print0 | xargs -0 sha1sum | sed 's# \+\./#\t#' | awk -F'\t' '{print $2"\t"$1}' | sort -k1,1 ) > master.sum || true | |
| ( cd origin-src && find . -type f -print0 | xargs -0 sha1sum | sed 's# \+\./#\t#' | awk -F'\t' '{print $2"\t"$1}' | sort -k1,1 ) > origin.sum || true | |
| join -t $'\t' -v1 -1 1 -2 1 master.sum origin.sum | awk -F'\t' '{print "A "$1}' > added.raw || true | |
| join -t $'\t' -v2 -1 1 -2 1 master.sum origin.sum | awk -F'\t' '{print "D "$1}' > deleted.raw || true | |
| join -t $'\t' -1 1 -2 1 master.sum origin.sum | awk -F'\t' '{if($2!=$3) print "M "$1}' > modified.raw || true | |
| awk '$1=="A" && $2 ~ /\.(mdx|tsx|ts)$/{print}' added.raw > changes.filtered || true | |
| awk '$1=="D" && $2 ~ /\.(mdx|tsx|ts)$/{print}' deleted.raw >> changes.filtered || true | |
| awk '$1=="M" && $2 ~ /\.(mdx|tsx|ts)$/{print}' modified.raw >> changes.filtered || true | |
| if [ -s changes.filtered ]; then | |
| echo "pr_needed=true" >> "$GITHUB_ENV" | |
| else | |
| echo "pr_needed=false" >> "$GITHUB_ENV" | |
| fi | |
| { | |
| echo "changes<<EOF" | |
| cat changes.filtered || true | |
| echo "EOF" | |
| } >> "$GITHUB_OUTPUT" | |
| - name: Update origin-src content | |
| if: ${{ env.pr_needed == 'true' }} | |
| shell: bash | |
| run: | | |
| set -Eeuo pipefail | |
| if git show-ref --quiet refs/remotes/origin/master-ko; then | |
| git checkout -B master-ko origin/master-ko | |
| else | |
| git checkout -B master-ko | |
| fi | |
| rsync -a --delete master-src/ origin-src/ | |
| git add -A origin-src | |
| if ! git diff --cached --quiet; then | |
| git commit -m "Sync origin-src with latest origin/master/src (auto)" | |
| fi | |
| - name: Find existing update-origin-src PR | |
| if: ${{ env.pr_needed == 'true' }} | |
| id: pr-branch | |
| shell: bash | |
| run: | | |
| set -Eeuo pipefail | |
| branch=$(gh pr list --json headRefName \ | |
| --jq '.[] | select(.headRefName | startswith("update-origin-src-")) | .headRefName' \ | |
| | head -n1) | |
| echo "branch=$branch" >> "$GITHUB_OUTPUT" | |
| - name: Force-push to existing branch | |
| if: ${{ env.pr_needed == 'true' && steps.pr-branch.outputs.branch != '' }} | |
| shell: bash | |
| run: | | |
| set -Eeuo pipefail | |
| git push origin master-ko:${{ steps.pr-branch.outputs.branch }} --force | |
| - name: Create new PR | |
| if: ${{ env.pr_needed == 'true' && steps.pr-branch.outputs.branch == '' }} | |
| shell: bash | |
| run: | | |
| set -Eeuo pipefail | |
| new_branch=update-origin-src-${{ github.run_id }} | |
| git checkout -b "$new_branch" | |
| git push origin "$new_branch" | |
| gh pr create \ | |
| --title "Update origin-src for translation" \ | |
| --body "Auto-sync **origin-src** with the latest **src** directory from **origin/master**." \ | |
| --head "$new_branch" \ | |
| --base master-ko | |
| # โ ๋ผ๋ฒจ(๊ธฐ๋ณธ + kind) ์์ผ๋ฉด ์์ฑ | |
| - name: Ensure labels exist (docs/i18n/tracker + kind labels) | |
| if: ${{ env.pr_needed == 'true' }} | |
| shell: bash | |
| run: | | |
| set -Eeuo pipefail | |
| owner="${GITHUB_REPOSITORY%/*}"; repo="${GITHUB_REPOSITORY#*/}" | |
| existing=$(gh api -X GET "repos/$owner/$repo/labels?per_page=200" --jq '.[].name' || true) | |
| has() { grep -Fxq "$1" <<< "$existing"; } | |
| ensure_label() { | |
| name="$1"; color="$2"; desc="$3" | |
| if ! has "$name"; then | |
| gh api -X POST "repos/$owner/$repo/labels" -f name="$name" -f color="$color" -f description="$desc" >/dev/null | |
| fi | |
| } | |
| ensure_label docs 0075ca "Documentation" | |
| ensure_label i18n c5def5 "Localization/Internationalization" | |
| ensure_label tracker 5319e7 "Tracker/Meta issue" | |
| ensure_label docs:add 0e8a16 "Docs task: Add" | |
| ensure_label docs:sync fbca04 "Docs task: Sync" | |
| ensure_label docs:migrate 1d76db "Docs task: Migrate" | |
| ensure_label docs:remove d93f0b "Docs task: Remove" | |
| # โ ์๋ธ ์ด์ ์์ฑ + (๊ธฐ์กด ์ด์์ผ ๊ฒฝ์ฐ) ๋ผ๋ฒจ ๋ณด๊ฐ + ๋ง์คํฐ ์ฒดํฌ๋ฆฌ์คํธ ๊ฐฑ์ | |
| - name: Create sub-issues and update master tracker | |
| if: ${{ env.pr_needed == 'true' }} | |
| shell: bash | |
| run: | | |
| set -Eeuo pipefail | |
| owner="${GITHUB_REPOSITORY%/*}"; repo="${GITHUB_REPOSITORY#*/}" | |
| awk '$1=="A"{print $2}' changes.filtered > added.list || true | |
| awk '$1=="M"{print $2}' changes.filtered > modified.list || true | |
| awk '$1=="D"{print $2}' changes.filtered > deleted.list || true | |
| awk -F/ '{b=$0; sub(/\.[^.]+$/,"",b); if($0 ~ /\.mdx$/) print b}' added.list | sort > added_mdx_base.list || true | |
| awk -F/ '{b=$0; sub(/\.[^.]+$/,"",b); if($0 ~ /\.tsx$/) print b}' deleted.list | sort > deleted_tsx_base.list || true | |
| comm -12 added_mdx_base.list deleted_tsx_base.list > migrate_base.list || true | |
| tracker_title="Docs: ๋ฒ์ญยท๋๊ธฐํ ๋ง์คํฐ ์ฒดํฌ๋ฆฌ์คํธ" | |
| tracker=$(gh api -X GET "repos/$owner/$repo/issues?state=open&labels=tracker&per_page=100" \ | |
| --jq '.[] | select(.title=="'"$tracker_title"'") | .number' | head -n1) | |
| if [ -z "$tracker" ]; then | |
| tracker_body=$'### ๋ฒ์ญ ์์ ์ฒดํฌ๋ฆฌ์คํธ\n\n(์๋ ์์ฑ. ์๋ธ ์ด์์ ์ฐ๋๋ ์ฒดํฌ๋ฐ์ค์ ๋๋ค)' | |
| tracker=$(gh api -X POST "repos/$owner/$repo/issues" \ | |
| -f title="$tracker_title" \ | |
| -f body="$tracker_body" \ | |
| -f labels[]="docs" -f labels[]="i18n" -f labels[]="tracker" \ | |
| --jq '.number') | |
| fi | |
| add_labels_if_missing() { | |
| local num="$1"; shift | |
| curr=$(gh api -X GET "repos/$owner/$repo/issues/$num" --jq '[.labels[].name] | join(",")') | |
| for lbl in "$@"; do | |
| if ! grep -q "\b${lbl}\b" <<< "$curr"; then | |
| gh api -X POST "repos/$owner/$repo/issues/$num/labels" -f labels[]="$lbl" >/dev/null | |
| fi | |
| done | |
| } | |
| create_issue() { | |
| file="$1" | |
| kind="$2" # Add | Sync | Migrate | Remove | |
| title="[Docs] $file โ $kind" | |
| slug=$(printf "%s" "$file|$kind" | sha1sum | awk '{print $1}') | |
| case "$kind" in | |
| Add) kind_label="docs:add" ;; | |
| Sync) kind_label="docs:sync" ;; | |
| Migrate) kind_label="docs:migrate" ;; | |
| Remove) kind_label="docs:remove" ;; | |
| *) kind_label="docs:sync" ;; | |
| esac | |
| existing=$(gh api -X GET "repos/$owner/$repo/issues?state=all&labels=docs,i18n&per_page=100" \ | |
| --jq '[.[] | select((.title=="'"$title"'") or (.body|tostring|contains("'"$slug"'")))] | first | .number' \ | |
| | tr -d '\n') | |
| if [ -z "$existing" ] || [ "$existing" = "null" ]; then | |
| issue_body=$'ํ์ผ: `'"$file"$'`\n์ ํ: '"$kind"$'\n\n### ์์ \n- [ ] ๋ฒ์ญ/๋๊ธฐํ\n- [ ] ๋ฆฌ๋ทฐ\n- [ ] PR\n\nTracked by: #'"$tracker"$'\n\n<!-- TRANSLATION_TRACKER:'"$slug"' -->' | |
| existing=$(gh api -X POST "repos/$owner/$repo/issues" \ | |
| -f title="$title" \ | |
| -f body="$issue_body" \ | |
| -f labels[]="docs" -f labels[]="i18n" -f labels[]="$kind_label" \ | |
| --jq '.number') | |
| else | |
| add_labels_if_missing "$existing" "docs" "i18n" "$kind_label" | |
| fi | |
| } | |
| # ์๋ธ ์ด์ ์์ฑ | |
| if [ -s modified.list ]; then | |
| while IFS= read -r f; do [ -n "$f" ] && create_issue "$f" "Sync"; done < modified.list | |
| fi | |
| if [ -s added.list ]; then | |
| if [ -s migrate_base.list ]; then | |
| grep -v -F -f <(sed 's/$/.mdx/' migrate_base.list) added.list > added_pure.list || true | |
| else | |
| cp added.list added_pure.list | |
| fi | |
| while IFS= read -r f; do [ -n "$f" ] && create_issue "$f" "Add"; done < added_pure.list | |
| fi | |
| if [ -s migrate_base.list ]; then | |
| while IFS= read -r b; do [ -n "$b" ] && create_issue "$b.mdx" "Migrate"; done < migrate_base.list | |
| fi | |
| if [ -s deleted.list ]; then | |
| if [ -s migrate_base.list ]; then | |
| grep -v -F -f <(sed 's/$/.tsx/' migrate_base.list) deleted.list > deleted_pure.list || true | |
| else | |
| cp deleted.list deleted_pure.list | |
| fi | |
| while IFS= read -r f; do [ -n "$f" ] && create_issue "$f" "Remove"; done < deleted_pure.list | |
| fi | |
| # ์ด๋ฆฐ ์๋ธ ์ด์ ์์ง(๋ผ๋ฒจ ํฌํจ) โ ๋ง์คํฐ ์ฒดํฌ๋ฆฌ์คํธ ๊ฐฑ์ | |
| gh api -X GET "repos/$owner/$repo/issues?state=open&labels=docs,i18n&per_page=100" \ | |
| --jq '.[] | select(.labels | any(.name=="tracker") | not) | "\(.number)\t\(.title)\t\([.labels[].name]|join(","))"' > open.tsv || true | |
| { | |
| echo "### ๋ฒ์ญ ์์ ์ฒดํฌ๋ฆฌ์คํธ" | |
| echo | |
| echo "#### 1) ๋ฒ์ญ ํน์ ๋ณ๊ฒฝ์ ๋ฐ์ ํ์" | |
| awk -F'\t' 'index($3,"docs:sync") {print "- [ ] #"$1" " gensub(/^\[Docs\] /,"","", $2)}' open.tsv | sort -k2 | |
| echo | |
| echo "#### 2) ๋ฒ์ญ ์ถ๊ฐ ํ์(์๋ก์ด ํ์ผ ์ถ๊ฐ)" | |
| awk -F'\t' 'index($3,"docs:add") {print "- [ ] #"$1" " gensub(/^\[Docs\] /,"","", $2)}' open.tsv | sort -k2 | |
| echo | |
| echo "#### 3) tsx -> mdx๋ก ๋ณ๊ฒฝ ์์ " | |
| awk -F'\t' 'index($3,"docs:migrate") {print "- [ ] #"$1" " gensub(/^\[Docs\] /,"","", $2)}' open.tsv | sort -k2 | |
| echo | |
| echo "#### 4) ์ญ์ ํ์" | |
| awk -F'\t' 'index($3,"docs:remove") {print "- [ ] #"$1" " gensub(/^\[Docs\] /,"","", $2)}' open.tsv | sort -k2 | |
| echo | |
| echo "> ์ฐธ๊ณ " | |
| echo "> - tsxโmdx ๋ณ๊ฒฝ ๋ฐ์ ์ 3)์ 4)๋ฅผ ์ฐ๊ณ ์ฒ๋ฆฌ" | |
| echo "> - ํ์ /์ฝ๋ ๋ณ๊ฒฝ์ ๋ฒ์ญ ๋ฒ์์์ ์ ์ธ" | |
| } > master.md | |
| gh issue edit "$tracker" --body-file master.md |