Skip to content

Commit 165f7e4

Browse files
committed
Stale translation warning
- add script to mark outdated translations - add workflow for stale translations - add label checks to deployment remove deprecated deployment workflows for API and frontend add deployment workflow for marking translations and deploying frontend/backend add script to mark outdated translations add workflow for marking stale translations consolidate translation marking workflow into deploy process Stale translation warning Stale translation warning Stale translation warning Stale translation warning add chars threshold add translation by Nexius add translation label check to deployment workflow
1 parent 4fde018 commit 165f7e4

File tree

4 files changed

+527
-1
lines changed

4 files changed

+527
-1
lines changed

.github/workflows/deploy-web.yml

Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ on:
55
branches:
66
- master
77

8+
permissions:
9+
contents: write
10+
811
jobs:
912
deploy:
1013
name: Deploy frontend
@@ -16,7 +19,86 @@ jobs:
1619
workflow_id: 42688838
1720
access_token: ${{ github.token }}
1821

19-
- uses: actions/checkout@v4
22+
- name: Checkout repository
23+
uses: actions/checkout@v4
24+
with:
25+
fetch-depth: 0
26+
27+
- name: Set up Node.js
28+
uses: actions/setup-node@v4
29+
with:
30+
node-version: '18'
31+
32+
- name: Check translation label
33+
id: translation-label
34+
env:
35+
GITHUB_TOKEN: ${{ github.token }}
36+
run: |
37+
LABEL_RESULT=$(node .github/workflows/scripts/check-translation-label.js --repo "${{ github.repository }}" --token "$GITHUB_TOKEN" --sha "${{ github.sha }}" --label "docs:translation-impact")
38+
echo "$LABEL_RESULT" >> "$GITHUB_OUTPUT"
39+
40+
- name: Get changed English documentation files
41+
id: changed-files
42+
if: steps.translation-label.outputs.label_present == 'true'
43+
run: |
44+
set -euo pipefail
45+
BEFORE="${{ github.event.before }}"
46+
if git rev-parse "$BEFORE^{commit}" >/dev/null 2>&1; then
47+
DIFF_BASE="$BEFORE"
48+
else
49+
DIFF_BASE=""
50+
fi
51+
52+
if [ -n "$DIFF_BASE" ]; then
53+
CHANGED_FILES=$(git diff --name-only "$DIFF_BASE" "${{ github.sha }}" | grep "^frontend/docs/.*\.md$" || true)
54+
else
55+
CHANGED_FILES=$(git ls-tree --name-only -r "${{ github.sha }}" | grep "^frontend/docs/.*\.md$" || true)
56+
fi
57+
58+
if [ -z "$CHANGED_FILES" ]; then
59+
echo "has_changes=false" >> "$GITHUB_OUTPUT"
60+
else
61+
if [ -n "$DIFF_BASE" ]; then
62+
printf '%s\n' "$CHANGED_FILES" > changed_english_docs_raw.txt
63+
node .github/workflows/scripts/filter-small-doc-changes.js "$DIFF_BASE" "${{ github.sha }}" changed_english_docs_raw.txt changed_english_docs.txt
64+
if [ -s changed_english_docs.txt ]; then
65+
echo "has_changes=true" >> "$GITHUB_OUTPUT"
66+
else
67+
echo "has_changes=false" >> "$GITHUB_OUTPUT"
68+
fi
69+
else
70+
printf '%s\n' "$CHANGED_FILES" > changed_english_docs.txt
71+
echo "has_changes=true" >> "$GITHUB_OUTPUT"
72+
fi
73+
fi
74+
75+
- name: Mark translations as outdated
76+
if: steps.translation-label.outputs.label_present == 'true' && steps.changed-files.outputs.has_changes == 'true'
77+
run: |
78+
node .github/workflows/scripts/mark-translations-outdated.js
79+
80+
- name: Check if translations were modified
81+
if: steps.translation-label.outputs.label_present == 'true' && steps.changed-files.outputs.has_changes == 'true'
82+
id: check-changes
83+
run: |
84+
if [ -n "$(git status --porcelain)" ]; then
85+
echo "translations_modified=true" >> "$GITHUB_OUTPUT"
86+
else
87+
echo "translations_modified=false" >> "$GITHUB_OUTPUT"
88+
fi
89+
90+
- name: Commit changes
91+
if: steps.translation-label.outputs.label_present == 'true' && steps.check-changes.outputs.translations_modified == 'true'
92+
run: |
93+
git config --local user.email "omp-bot@users.noreply.github.com"
94+
git config --local user.name "omp-bot"
95+
git add frontend/i18n/
96+
git commit -m "Mark translations as potentially outdated (post-merge)"
97+
98+
- name: Push changes
99+
if: steps.translation-label.outputs.label_present == 'true' && steps.check-changes.outputs.translations_modified == 'true'
100+
run: |
101+
git push origin HEAD:${{ github.ref }}
20102
21103
- name: Cache ~/.npm for npm ci
22104
uses: actions/cache@v4
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
#!/usr/bin/env node
2+
3+
const https = require('https');
4+
5+
const args = process.argv.slice(2);
6+
const options = {
7+
repo: process.env.GITHUB_REPOSITORY || '',
8+
token: process.env.GITHUB_TOKEN || '',
9+
sha: process.env.GITHUB_SHA || '',
10+
label: '',
11+
pr: '',
12+
};
13+
14+
for (let i = 0; i < args.length; i += 2) {
15+
const key = args[i];
16+
const value = args[i + 1] || '';
17+
switch (key) {
18+
case '--repo':
19+
options.repo = value;
20+
break;
21+
case '--token':
22+
options.token = value;
23+
break;
24+
case '--sha':
25+
options.sha = value;
26+
break;
27+
case '--label':
28+
options.label = value;
29+
break;
30+
case '--pr':
31+
options.pr = value;
32+
break;
33+
default:
34+
i -= 1;
35+
}
36+
}
37+
38+
if (!options.repo || !options.token || !options.label) {
39+
console.error('Missing required arguments: repo, token, and label');
40+
process.exit(1);
41+
}
42+
43+
const githubRequest = (path, accept) =>
44+
new Promise((resolve, reject) => {
45+
const req = https.request(
46+
{
47+
hostname: 'api.github.com',
48+
path,
49+
method: 'GET',
50+
headers: {
51+
Authorization: `Bearer ${options.token}`,
52+
'User-Agent': 'translations-workflow',
53+
Accept: accept || 'application/vnd.github+json',
54+
},
55+
},
56+
res => {
57+
let body = '';
58+
res.on('data', chunk => {
59+
body += chunk;
60+
});
61+
res.on('end', () => {
62+
if (res.statusCode >= 200 && res.statusCode < 300) {
63+
try {
64+
resolve(JSON.parse(body));
65+
} catch (err) {
66+
reject(err);
67+
}
68+
} else {
69+
reject(new Error(`GitHub API responded with ${res.statusCode}: ${body}`));
70+
}
71+
});
72+
}
73+
);
74+
req.on('error', reject);
75+
req.end();
76+
});
77+
78+
const detectPrNumber = async () => {
79+
if (options.pr) {
80+
return options.pr;
81+
}
82+
if (!options.sha) {
83+
return '';
84+
}
85+
86+
try {
87+
const pulls = await githubRequest(
88+
`/repos/${options.repo}/commits/${options.sha}/pulls`,
89+
'application/vnd.github.groot-preview+json'
90+
);
91+
if (Array.isArray(pulls) && pulls.length > 0) {
92+
return String(pulls[0].number);
93+
}
94+
} catch (error) {
95+
console.error(`Failed to determine PR number: ${error.message}`);
96+
}
97+
return '';
98+
};
99+
100+
const main = async () => {
101+
try {
102+
const prNumber = await detectPrNumber();
103+
if (!prNumber) {
104+
process.stdout.write('label_present=false');
105+
return;
106+
}
107+
108+
const issue = await githubRequest(`/repos/${options.repo}/issues/${prNumber}`);
109+
const labels = Array.isArray(issue.labels) ? issue.labels.map(label => label.name) : [];
110+
const hasLabel = labels.includes(options.label);
111+
process.stdout.write(`label_present=${hasLabel ? 'true' : 'false'}`);
112+
} catch (error) {
113+
console.error(`Failed to load labels: ${error.message}`);
114+
process.stdout.write('label_present=false');
115+
}
116+
};
117+
118+
main();

0 commit comments

Comments
 (0)