-
Notifications
You must be signed in to change notification settings - Fork 428
146 lines (131 loc) · 5.29 KB
/
Copy pathtranslate_docs.yml
File metadata and controls
146 lines (131 loc) · 5.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
name: Translate Docs
on:
push:
branches: [main]
paths:
- 'content/docs/**'
# Exclude generated translations of any locale. A `*.<locale>.mdx` or
# `meta.<locale>.json` file is bot output, never a translation source, so it
# must not retrigger this workflow. Keep both two-letter and regional locale
# patterns here, matching TARGET_LOCALES in lib/i18n/config.ts.
- '!content/docs/**/*.[a-z][a-z].mdx'
- '!content/docs/**/*.[a-z][a-z]-[A-Z][A-Z].mdx'
- '!content/docs/**/meta.[a-z][a-z].json'
- '!content/docs/**/meta.[a-z][a-z]-[A-Z][A-Z].json'
# Convergence sweep. A push only translates after a content change, and adding a
# new language doesn't touch content/docs at all — so a big batch (several new
# locales and/or long files) can't fully land in the single push-triggered run
# under the flex-tier rate limit. This half-hourly run writes generated docs to
# TRANSLATE_BRANCH and keeps translation memory in the Actions cache, so main stays
# free of partial progress commits and cache files.
schedule:
- cron: '*/30 * * * *'
workflow_dispatch:
inputs:
force:
description: 'Retranslate everything (ignore the cache)'
type: boolean
default: false
permissions:
contents: write
env:
TRANSLATE_BRANCH: automation/docs-translations
concurrency:
group: translate-docs
cancel-in-progress: false
jobs:
translate:
runs-on: ubuntu-latest
environment: Production
steps:
- uses: actions/checkout@v4
with:
# Full history so the long-lived translation branch can merge current
# main before each convergence pass.
fetch-depth: 0
- name: Prepare translation branch
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git fetch origin "+refs/heads/main:refs/remotes/origin/main"
if git fetch origin "+refs/heads/${TRANSLATE_BRANCH}:refs/remotes/origin/${TRANSLATE_BRANCH}" 2>/dev/null; then
git switch -c "$TRANSLATE_BRANCH" "origin/$TRANSLATE_BRANCH"
git merge --no-edit origin/main
else
git switch -c "$TRANSLATE_BRANCH" origin/main
fi
- name: Restore translation memory
uses: actions/cache@v4
with:
path: content/.i18n-cache
key: translate-docs-${{ github.run_id }}
restore-keys: |
translate-docs-
- name: Seed translation memory from git history
run: |
if [ -d content/.i18n-cache ]; then
exit 0
fi
# First run after removing cache files from main: seed from the parent of
# the cache-removal commit, then unstage it so the files stay out of git.
seed_commit=$(git rev-list -n 1 HEAD -- content/.i18n-cache || true)
if [ -n "$seed_commit" ]; then
git checkout "${seed_commit}^" -- content/.i18n-cache || true
git reset -- content/.i18n-cache || true
fi
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: pnpm
- run: pnpm install --frozen-lockfile
- name: Translate docs
env:
OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }}
OPENROUTER_TRANSLATE_MODEL: ${{ secrets.OPENROUTER_TRANSLATE_MODEL }}
run: |
FLAGS=""
if [ "${{ inputs.force }}" = "true" ]; then
FLAGS="--force"
fi
npx tsx scripts/translate.ts $FLAGS
- name: Commit translations to branch
run: |
git add content/docs
if git diff --cached --quiet; then
echo "No translation changes to commit"
else
# [skip ci] keeps the long-lived translation branch from running CI on
# every half-hourly convergence commit. Main only changes when this branch
# is intentionally merged.
git commit --no-verify -m "chore: update docs translations [skip ci]"
fi
if git show-ref --verify --quiet "refs/remotes/origin/${TRANSLATE_BRANCH}"; then
base="origin/${TRANSLATE_BRANCH}"
else
base="origin/main"
fi
ahead=$(git rev-list --count "${base}..HEAD")
if [ "$ahead" -eq 0 ]; then
echo "Translation branch already up to date"
exit 0
fi
pushed=false
for attempt in 1 2 3 4 5; do
if git push origin HEAD:"$TRANSLATE_BRANCH"; then
pushed=true
break
fi
echo "push attempt $attempt rejected (remote advanced); merging latest branch/main"
git fetch origin "+refs/heads/main:refs/remotes/origin/main"
git fetch origin "+refs/heads/${TRANSLATE_BRANCH}:refs/remotes/origin/${TRANSLATE_BRANCH}" || true
if git show-ref --verify --quiet "refs/remotes/origin/${TRANSLATE_BRANCH}"; then
git merge --no-edit "origin/${TRANSLATE_BRANCH}"
fi
git merge --no-edit origin/main
sleep 5
done
if [ "$pushed" != "true" ]; then
echo "::error::failed to push translations to $TRANSLATE_BRANCH after 5 attempts"
exit 1
fi