ci: add Localization Check CI (#600)

Signed-off-by: Gadfly <gadfly@gadfly.vip>
This commit is contained in:
GadflyFang 2024-10-25 14:22:38 +08:00 committed by GitHub
parent fa4f0a6bd4
commit 32de28c16e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 300 additions and 1 deletions

View file

@ -292,3 +292,8 @@ indent_size = 2
end_of_line = lf end_of_line = lf
[*.{cmd,bat}] [*.{cmd,bat}]
end_of_line = crlf end_of_line = crlf
# YAML files
[*.{yml,yaml}]
indent_size = 2
end_of_line = lf

59
.github/scripts/localization-check.js vendored Normal file
View file

@ -0,0 +1,59 @@
const fs = require('fs-extra');
const path = require('path');
const xml2js = require('xml2js');
const repoRoot = path.join(__dirname, '../../');
const localesDir = path.join(repoRoot, 'src/Resources/Locales');
const enUSFile = path.join(localesDir, 'en_US.axaml');
const outputFile = path.join(repoRoot, 'TRANSLATION.md');
const readmeFile = path.join(repoRoot, 'README.md');
const parser = new xml2js.Parser();
async function parseXml(filePath) {
const data = await fs.readFile(filePath);
return parser.parseStringPromise(data);
}
async function calculateTranslationRate() {
const enUSData = await parseXml(enUSFile);
const enUSKeys = new Set(enUSData.ResourceDictionary['x:String'].map(item => item.$['x:Key']));
const translationRates = [];
const badges = [];
const files = (await fs.readdir(localesDir)).filter(file => file !== 'en_US.axaml' && file.endsWith('.axaml'));
// Add en_US badge first
badges.push(`![en_US](https://img.shields.io/badge/en__US-100%25-brightgreen)`);
for (const file of files) {
const filePath = path.join(localesDir, file);
const localeData = await parseXml(filePath);
const localeKeys = new Set(localeData.ResourceDictionary['x:String'].map(item => item.$['x:Key']));
const missingKeys = [...enUSKeys].filter(key => !localeKeys.has(key));
const translationRate = ((enUSKeys.size - missingKeys.length) / enUSKeys.size) * 100;
translationRates.push(`### ${file}: ${translationRate.toFixed(2)}%\n`);
translationRates.push(`<details>\n<summary>Missing Keys</summary>\n\n${missingKeys.map(key => `- ${key}`).join('\n')}\n\n</details>`);
// Add badges
const locale = file.replace('.axaml', '').replace('_', '__');
const badgeColor = translationRate === 100 ? 'brightgreen' : translationRate >= 75 ? 'yellow' : 'red';
badges.push(`![${locale}](https://img.shields.io/badge/${locale}-${translationRate.toFixed(2)}%25-${badgeColor})`);
}
console.log(translationRates.join('\n\n'));
await fs.writeFile(outputFile, translationRates.join('\n\n'), 'utf8');
// Update README.md
let readmeContent = await fs.readFile(readmeFile, 'utf8');
const badgeSection = `## Translation Status\n\n${badges.join(' ')}`;
console.log(badgeSection);
readmeContent = readmeContent.replace(/## Translation Status\n\n.*\n\n/, badgeSection + '\n\n');
await fs.writeFile(readmeFile, readmeContent, 'utf8');
}
calculateTranslationRate().catch(err => console.error(err));

View file

@ -0,0 +1,42 @@
name: Localization Check
on:
push:
branches: [ develop ]
paths:
- 'src/Resources/Locales/**'
- 'README.md'
workflow_dispatch:
workflow_call:
jobs:
localization-check:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20.x'
- name: Install dependencies
run: npm install fs-extra@11.2.0 path@0.12.7 xml2js@0.6.2
- name: Run localization check
run: node .github/scripts/localization-check.js
- name: Commit changes
run: |
git config --global user.name 'github-actions[bot]'
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
if [ -n "$(git status --porcelain)" ]; then
git add README.md TRANSLATION.md
git commit -m 'doc: Update translation status and missing keys'
git push
else
echo "No changes to commit"
fi
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

4
.gitignore vendored
View file

@ -23,6 +23,10 @@ ehthumbs_vista.db
bin/ bin/
obj/ obj/
# ignore ci node files
node_modules/
package.json
package-lock.json
build/resources/ build/resources/
build/SourceGit/ build/SourceGit/

View file

@ -41,6 +41,10 @@
> [!WARNING] > [!WARNING]
> **Linux** only tested on **Debian 12** on both **X11** & **Wayland**. > **Linux** only tested on **Debian 12** on both **X11** & **Wayland**.
## Translation Status
![en_US](https://img.shields.io/badge/en__US-100%25-brightgreen) ![de__DE](https://img.shields.io/badge/de__DE-98.95%25-yellow) ![fr__FR](https://img.shields.io/badge/fr__FR-90.38%25-yellow) ![pt__BR](https://img.shields.io/badge/pt__BR-93.53%25-yellow) ![ru__RU](https://img.shields.io/badge/ru__RU-98.80%25-yellow) ![zh__CN](https://img.shields.io/badge/zh__CN-98.95%25-yellow) ![zh__TW](https://img.shields.io/badge/zh__TW-99.70%25-yellow)
## How to Use ## How to Use
**To use this tool, you need to install Git(>=2.23.0) first.** **To use this tool, you need to install Git(>=2.23.0) first.**

View file

@ -16,6 +16,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{
.github\workflows\ci.yml = .github\workflows\ci.yml .github\workflows\ci.yml = .github\workflows\ci.yml
.github\workflows\package.yml = .github\workflows\package.yml .github\workflows\package.yml = .github\workflows\package.yml
.github\workflows\release.yml = .github\workflows\release.yml .github\workflows\release.yml = .github\workflows\release.yml
.github\workflows\localization-check.yml = .github\workflows\localization-check.yml
EndProjectSection EndProjectSection
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{49A7C2D6-558C-4FAA-8F5D-EEE81497AED7}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{49A7C2D6-558C-4FAA-8F5D-EEE81497AED7}"

184
TRANSLATION.md Normal file
View file

@ -0,0 +1,184 @@
### de_DE.axaml: 98.95%
<details>
<summary>Missing Keys</summary>
- Text.Configure.Git.EnableSignOff
- Text.Configure.IssueTracker.AddSampleGitLabIssue
- Text.Configure.IssueTracker.AddSampleGitLabMergeRequest
- Text.Preference.Advanced
- Text.Preference.AI.AnalyzeDiffPrompt
- Text.Preference.AI.GenerateSubjectPrompt
- Text.WorkingCopy.ConfirmCommitWithoutFiles
</details>
### fr_FR.axaml: 90.38%
<details>
<summary>Missing Keys</summary>
- Text.About.Chart
- Text.AIAssistant
- Text.AIAssistant.Tip
- Text.CherryPick.AppendSourceToMessage
- Text.CherryPick.Mainline
- Text.CherryPick.Mainline.Tips
- Text.CommitCM.CherryPickMultiple
- Text.CommitCM.SquashCommitsSinceThis
- Text.CommitDetail.Info.WebLinks
- Text.Configure.Git.DefaultRemote
- Text.Configure.Git.EnableSignOff
- Text.Configure.IssueTracker.AddSampleGitLabIssue
- Text.Configure.IssueTracker.AddSampleGitLabMergeRequest
- Text.ConfigureWorkspace
- Text.ConfigureWorkspace.Color
- Text.ConfigureWorkspace.Restore
- Text.ConventionalCommit
- Text.ConventionalCommit.BreakingChanges
- Text.ConventionalCommit.ClosedIssue
- Text.ConventionalCommit.Detail
- Text.ConventionalCommit.Scope
- Text.ConventionalCommit.ShortDescription
- Text.ConventionalCommit.Type
- Text.Diff.IgnoreWhitespace
- Text.Discard.IncludeIgnored
- Text.FileHistory.FileChange
- Text.GitLFS.Locks.OnlyMine
- Text.Histories.Header.AuthorTime
- Text.Histories.Tips
- Text.Histories.Tips.MacOS
- Text.Histories.Tips.Prefix
- Text.Hotkeys.Repo.CommitWithAutoStage
- Text.Hotkeys.Repo.DiscardSelected
- Text.MoveRepositoryNode
- Text.MoveRepositoryNode.Target
- Text.Preference.Advanced
- Text.Preference.AI
- Text.Preference.AI.AnalyzeDiffPrompt
- Text.Preference.AI.ApiKey
- Text.Preference.AI.GenerateSubjectPrompt
- Text.Preference.AI.Model
- Text.Preference.AI.Server
- Text.Preference.General.ShowAuthorTime
- Text.Preference.Integration
- Text.Preference.Shell
- Text.Preference.Shell.Type
- Text.Preference.Shell.Path
- Text.Repository.AutoFetching
- Text.Repository.EnableReflog
- Text.Repository.Search.InCurrentBranch
- Text.ScanRepositories
- Text.ScanRepositories.RootDir
- Text.Squash.Into
- Text.Stash.OnlyStagedChanges
- Text.Stash.TipForSelectedFiles
- Text.Statistics.Overview
- Text.TagCM.CopyMessage
- Text.Welcome.Move
- Text.Welcome.ScanDefaultCloneDir
- Text.WorkingCopy.CommitTip
- Text.WorkingCopy.CommitWithAutoStage
- Text.WorkingCopy.ConfirmCommitWithoutFiles
- Text.Workspace
- Text.Workspace.Configure
</details>
### pt_BR.axaml: 93.53%
<details>
<summary>Missing Keys</summary>
- Text.About.Chart
- Text.AIAssistant
- Text.AIAssistant.Tip
- Text.CherryPick.AppendSourceToMessage
- Text.CherryPick.Mainline
- Text.CherryPick.Mainline.Tips
- Text.CommitCM.CherryPickMultiple
- Text.CommitCM.SquashCommitsSinceThis
- Text.CommitDetail.Info.ContainsIn
- Text.CommitDetail.Info.ContainsIn.Title
- Text.CommitDetail.Info.WebLinks
- Text.Configure.Git.DefaultRemote
- Text.Configure.Git.EnableSignOff
- Text.Configure.IssueTracker.AddSampleGitLabIssue
- Text.Configure.IssueTracker.AddSampleGitLabMergeRequest
- Text.ConfigureWorkspace
- Text.ConfigureWorkspace.Color
- Text.ConfigureWorkspace.Restore
- Text.ConventionalCommit
- Text.ConventionalCommit.BreakingChanges
- Text.ConventionalCommit.ClosedIssue
- Text.ConventionalCommit.Detail
- Text.ConventionalCommit.Scope
- Text.ConventionalCommit.ShortDescription
- Text.ConventionalCommit.Type
- Text.CopyAllText
- Text.Discard.IncludeIgnored
- Text.FileHistory.FileContent
- Text.FileHistory.FileChange
- Text.GitLFS.Locks.OnlyMine
- Text.MoveRepositoryNode
- Text.MoveRepositoryNode.Target
- Text.Preference.Advanced
- Text.Push.CheckSubmodules
- Text.Squash.Into
- Text.Stash.OnlyStagedChanges
- Text.Stash.TipForSelectedFiles
- Text.Statistics.Overview
- Text.TagCM.CopyMessage
- Text.WorkingCopy.Staged.UnstageAll
- Text.WorkingCopy.Unstaged
- Text.WorkingCopy.Unstaged.Stage
- Text.WorkingCopy.Unstaged.StageAll
</details>
### ru_RU.axaml: 98.80%
<details>
<summary>Missing Keys</summary>
- Text.Configure.Git.EnableSignOff
- Text.Configure.IssueTracker.AddSampleGitLabIssue
- Text.Configure.IssueTracker.AddSampleGitLabMergeRequest
- Text.Preference.Advanced
- Text.Preference.AI.AnalyzeDiffPrompt
- Text.Preference.AI.GenerateSubjectPrompt
- Text.Repository.EnableReflog
- Text.WorkingCopy.ConfirmCommitWithoutFiles
</details>
### zh_CN.axaml: 98.95%
<details>
<summary>Missing Keys</summary>
- Text.Preference.AI
- Text.Preference.AI.AnalyzeDiffPrompt
- Text.Preference.AI.ApiKey
- Text.Preference.AI.GenerateSubjectPrompt
- Text.Preference.AI.Model
- Text.Preference.AI.Server
- Text.RemoteCM.Prune.Target
</details>
### zh_TW.axaml: 99.70%
<details>
<summary>Missing Keys</summary>
- Text.Preference.AI.AnalyzeDiffPrompt
- Text.Preference.AI.GenerateSubjectPrompt
</details>