forked from nvdaaddons/AddonTemplate
-
Notifications
You must be signed in to change notification settings - Fork 4
Add scripts to allow addons from personal repos to be synchronized with Crowdin #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
nvdaes
wants to merge
108
commits into
nvaccess:master
Choose a base branch
from
nvdaes:l10n
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from 9 commits
Commits
Show all changes
108 commits
Select commit
Hold shift + click to select a range
28c060d
Add scripts to allow addons from personal repos to be synchronized wi…
nvdaes 4669430
use a json file to store addonId, and use it to filter files to get C…
nvdaes b188560
Try to get files just for the current add-on
nvdaes 7092615
Add workflow to export an add-on to Crowdin (authors would need to be…
nvdaes e89640d
Use buildVars, not metadata.json file
nvdaes 4c7771b
Add userAccount to buildVars, and step to get addon-id to GitHub work…
nvdaes c529cee
Update files after testing exporting an add-on to Crowdin, needs refi…
nvdaes 186b755
Add python version file
nvdaes f1fbf8e
Improve pyproject and update precommit config after testing that chec…
nvdaes b867a9a
Restore rules
nvdaes 47ed91c
Restore pyproject
nvdaes 402002e
Improve uv project
nvdaes d820711
Remove files
nvdaes 9f6b3dc
Calculate hash of i18nSources
nvdaes 4c938ec
Update workflow
nvdaes a303210
Update _l10n
nvdaes a0d02da
Upload md file
nvdaes a8d4252
Updates
nvdaes 1a1e6fd
Update l10nUtil
nvdaes d2395b0
Update workflow
nvdaes e4dafe1
Update readme
nvdaes f76904e
Update readme.md
nvdaes aea5eba
Update _l10n/crowdinSync.py
nvdaes f7ccaf6
Add setOutput.py to separate Python code from yaml file
nvdaes 0276e22
Remove bad comment
nvdaes 253eb46
Reset pyproject to master
nvdaes c51e7ad
reset .pre-commit configuration to master
nvdaes cd4816c
Remove userAccount variable, since we use markdown, not xliff
nvdaes 314220b
Update or add files from scratch depending on existence of hashFile
nvdaes f3e8b8d
Use addMd and addPotFromScratch outputs
nvdaes de4fa15
Update dependencies
nvdaes 46a105a
Update setOutput
nvdaes 053d4de
Update workflow
nvdaes 4a3f5a0
Update lock
nvdaes 3c1a73e
Merge branch 'master' into l10n
nvdaes dbe74dc
Verify uv lock
nvdaes e717292
Add uv to dependencies in case this is relevant to verify the lock ac…
nvdaes c4ed575
Remove debug statement
nvdaes befa647
Run pre-commit
nvdaes 05c8161
Update dependencies
nvdaes 9a0f62a
Deleted Pyproject to avoid conflicts
nvdaes 4abd788
Reset pyproject to master
nvdaes c256364
Remove _l10n since this will be added as a submodule
nvdaes 0505a3b
Don't run pre-commit since it requires a different token to access hooks
nvdaes fd2554b
Merge translations into branch
nvdaes b30f46f
Add project id without using vars
nvdaes 70293c8
Schedule workflow
nvdaes da09c8c
Rename workflow
nvdaes 5c52f33
Create PR
nvdaes d0d5e03
Don't create a PR since this n¡may need a personal access token
nvdaes b40f94a
Update removing permissions for PR
nvdaes cb7807e
Update Python version compatible with ubuntu-latest
nvdaes 1449a01
Add dry-run
nvdaes 697d048
Optimize workflow to test with act and docker locally
nvdaes 8c9247b
Update uv.lock
nvdaes a8469fb
Merge branch 'master' into l10n
nvdaes 6089057
Add workflow call to build the add-on, so it can be reused in other w…
nvdaes d8154a9
Update workflow for testing
nvdaes e699abc
Improve workflow to download files from Crowdin
nvdaes 5eafa64
Update setOutputs to set just add-on id to download translations
nvdaes 0eb3223
[crowdinL10n.yml] improve CI translation workflow
abdel792 a195110
Remove duplicate setOutputs.py from .github/workflows
abdel792 9ed44a3
Merge pull request #2 from abdel792/l10nImprovements
nvdaes e62bd5b
Update lock
nvdaes 37c4d4f
Merge
nvdaes 91995bd
Try to fix pre-commit configuration
nvdaes 0c613be
Reset gitignore to master
nvdaes 0b65072
Require polib 1.2.0
nvdaes f9ba8fe
Update lock file
nvdaes 8e514ba
Remove sha256 file
nvdaes 9c64247
Remove verification of lock file in pre-commit config, not present in…
nvdaes 7589fef
Remove Crowdin client
nvdaes 94b1a88
Update lock file
nvdaes 65290e4
Enhance Crowdin l10n workflow with MD quality evaluation and comparis…
abdel792 059bb53
Merge pull request #3 from abdel792/l10nImprovements
nvdaes c9c3bab
Run pre-commit
nvdaes 25dcb5d
Fix conflicts
nvdaes b1d2acf
Restore deleted space
nvdaes 263b7e2
Update lock file
nvdaes f6e18c2
Remove score staff
nvdaes 5573061
Add ps1 script and rename setOutputs.py
nvdaes 87cbed4
Run ps1 script from workflow
nvdaes 1a18717
Change python version to 3.13
nvdaes 471a320
Update lock file
nvdaes e50a716
Fix checkTranslation script according to pre-commit
nvdaes f5150cb
Remove getAddonInfo step
nvdaes 3c7093c
Update scripts and workflow
nvdaes 065a16f
Fix pyright
nvdaes c4dd521
Add markdownTranslate
nvdaes 00cf8cf
Update markdownTranslate
nvdaes 480c70e
Exclude markdownTranslate from pyright, it contains many errors
nvdaes ce2d2da
Update source files
nvdaes 3981ece
Updates
nvdaes 0def05d
Fix files with pre-commit
nvdaes 1c92aab
refactor: use Crowdin API for translation checks and optimize file se…
abdel792 9b5bf84
Merge pull request #4 from abdel792/l10nImprovements
nvdaes c5e4076
Add crowdin api client
nvdaes c098392
Add dependencies
nvdaes 39416a0
Remove limit for list of files, fetch all
nvdaes 2396864
Improvements
nvdaes 94929e7
Updates
nvdaes 57d46f5
Add language mappings
nvdaes 74388d0
Fix
nvdaes 1f8eb84
refactor: modernize translation workflow and integrate language mappings
abdel792 ef0a614
docs: update readme with translation workflow instructions
abdel792 92e1cd6
docs: fix translation mailing list address in readme.md
abdel792 f92a73f
Merge pull request #5 from abdel792/l10nImprovements
nvdaes 6a884c0
Fix readme
nvdaes File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,90 @@ | ||
| name: Export add-on to Crowdin | ||
|
|
||
| on: | ||
|
|
||
| workflow_dispatch: | ||
| inputs: | ||
| update: | ||
| description: 'true to update preexisting sources, false to add them from scratch' | ||
| type: boolean | ||
| required: false | ||
| concurrency: | ||
| group: ${{ github.workflow }}-${{ github.ref }} | ||
| cancel-in-progress: true | ||
| jobs: | ||
| build: | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: write | ||
| steps: | ||
| - name: Checkout add-on | ||
| uses: actions/checkout@v6 | ||
| - name: "Set up Python" | ||
| uses: actions/setup-python@v6 | ||
| with: | ||
| python-version-file: ".python-version" | ||
| - name: Install dependencies | ||
| run: | | ||
| python -m pip install --upgrade pip | ||
| pip install scons markdown | ||
| sudo apt update | ||
| sudo apt install gettext | ||
| - name: Build add-on and pot file | ||
| run: | | ||
| scons | ||
| scons pot | ||
| - name: Install the latest version of uv | ||
| uses: astral-sh/setup-uv@v7 | ||
| - name: Get add-on id | ||
| id: getAddonId | ||
| shell: python | ||
| run: | | ||
| import os, sys | ||
| sys.path.insert(0, os.getcwd()) | ||
| import buildVars | ||
| addonId = buildVars.addon_info["addon_name"] | ||
| name = 'addonId' | ||
| value = addonId | ||
| with open(os.environ['GITHUB_OUTPUT'], 'a') as f: | ||
| f.write(f"{name}={value}") | ||
| - name: Generate xliff | ||
| if: ${{ !inputs.update }} | ||
| run: | | ||
| uv run ./_l10n/markdownTranslate.py generateXliff -m readme.md -o ${{ steps.getAddonId.outputs.addonId }}.xliff | ||
| - name: update xliff | ||
| if: ${{ inputs.update }} | ||
| run: | | ||
| uv run ./_l10n/markdownTranslate.py updateXliff -x ${{ steps.getAddonId.outputs.addonId }}.xliff -m readme.md -o ${{ steps.getAddonId.outputs.addonId }}.xliff.temp | ||
| mv ${{ steps.getAddonId.outputs.addonId }}.xliff.temp ${{ steps.getAddonId.outputs.addonId }}.xliff | ||
| fi | ||
| - name: Upload to Crowdin | ||
| if: ${{ !inputs.update }} | ||
| run: | | ||
| uv run ./_l10n/l10nUtil.py uploadSourceFile --localFilePath=${{ steps.getAddonId.outputs.addonId }}.xliff | ||
| uv run ./_l10n/l10nUtil.py uploadSourceFile --localFilePath=${{ steps.getAddonId.outputs.addonId }}.pot | ||
| env: | ||
| crowdinProjectID: ${{ vars.CROWDIN_ID }} | ||
| crowdinAuthToken: ${{ secrets.CROWDIN_TOKEN }} | ||
| - name: Update sources | ||
| if: ${{ inputs.update }} | ||
| run: | | ||
| uv run ./_l10n/crowdinSync.py uploadSourceFile ${{ steps.getAddonId.outputs.addonId }}.pot | ||
| uv run ./_l10n/crowdinSync.py uploadSourceFile ${{ steps.getAddonId.outputs.addonId }}.xliff | ||
| env: | ||
| crowdinProjectID: ${{ vars.CROWDIN_ID }} | ||
| crowdinAuthToken: ${{ secrets.CROWDIN_TOKEN }} | ||
| - name: Commit and push json file | ||
| id: commit | ||
| run: | | ||
| git config --local user.name github-actions | ||
| git config --local user.email github-actions@github.com | ||
| git status | ||
| git add _l10n/l10n.json | ||
| if git diff --staged --quiet; then | ||
| echo "Nothing added to commit." | ||
| echo "has_changes=false" >> $GITHUB_OUTPUT | ||
| else | ||
| echo "has_changes=true" >> $GITHUB_OUTPUT | ||
| git commit -m "Update Crowdin file ids" | ||
| git push | ||
| fi |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,92 @@ | ||
| # Copied from https://github.com/nvaccess/nvda | ||
| # https://pre-commit.ci/ | ||
| # Configuration for Continuous Integration service | ||
| ci: | ||
| # Pyright does not seem to work in pre-commit CI | ||
| skip: [pyright] | ||
| autoupdate_schedule: monthly | ||
| autoupdate_commit_msg: "Pre-commit auto-update" | ||
| autofix_commit_msg: "Pre-commit auto-fix" | ||
| submodules: true | ||
|
|
||
| default_language_version: | ||
| python: python3.13 | ||
|
|
||
| repos: | ||
| - repo: https://github.com/pre-commit/pre-commit-hooks | ||
| rev: v4.3.0 | ||
| hooks: | ||
| - id: check-ast | ||
| - id: check-case-conflict | ||
| - id: check-yaml | ||
| - repo: https://github.com/pre-commit-ci/pre-commit-ci-config | ||
| rev: v1.6.1 | ||
| hooks: | ||
| - id: check-pre-commit-ci-config | ||
|
|
||
| - repo: meta | ||
| hooks: | ||
| # ensures that exclude directives apply to any file in the repository. | ||
| - id: check-useless-excludes | ||
| # ensures that the configured hooks apply to at least one file in the repository. | ||
| - id: check-hooks-apply | ||
|
|
||
| - repo: https://github.com/pre-commit/pre-commit-hooks | ||
| rev: v5.0.0 | ||
| hooks: | ||
| # Prevents commits to certain branches | ||
| - id: no-commit-to-branch | ||
| args: ["--branch", "main", ] | ||
| # Checks that large files have not been added. Default cut-off for "large" files is 500kb. | ||
| - id: check-added-large-files | ||
| # Checks python syntax | ||
| - id: check-ast | ||
| # Checks for filenames that will conflict on case insensitive filesystems (the majority of Windows filesystems, most of the time) | ||
| - id: check-case-conflict | ||
| # Checks for artifacts from resolving merge conflicts. | ||
| - id: check-merge-conflict | ||
| # Checks Python files for debug statements, such as python's breakpoint function, or those inserted by some IDEs. | ||
| - id: debug-statements | ||
| # Removes trailing whitespace. | ||
| - id: trailing-whitespace | ||
| types_or: [python, c, c++, batch, markdown, toml, yaml, powershell] | ||
| # Ensures all files end in 1 (and only 1) newline. | ||
| - id: end-of-file-fixer | ||
| types_or: [python, c, c++, batch, markdown, toml, yaml, powershell] | ||
| # Removes the UTF-8 BOM from files that have it. | ||
| # See https://github.com/nvaccess/nvda/blob/master/projectDocs/dev/codingStandards.md#encoding | ||
| - id: fix-byte-order-marker | ||
| types_or: [python, c, c++, batch, markdown, toml, yaml, powershell] | ||
| # Validates TOML files. | ||
| - id: check-toml | ||
| # Validates YAML files. | ||
| - id: check-yaml | ||
| # Ensures that links to lines in files under version control point to a particular commit. | ||
| - id: check-vcs-permalinks | ||
| # Avoids using reserved Windows filenames. | ||
| - id: check-illegal-windows-names | ||
| - repo: https://github.com/asottile/add-trailing-comma | ||
| rev: v3.2.0 | ||
| hooks: | ||
| # Ruff preserves indent/new-line formatting of function arguments, list items, and similar iterables, | ||
| # if a trailing comma is added. | ||
| # This adds a trailing comma to args/iterable items in case it was missed. | ||
| - id: add-trailing-comma | ||
|
|
||
| - repo: https://github.com/astral-sh/ruff-pre-commit | ||
| # Matches Ruff version in pyproject. | ||
| rev: v0.12.7 | ||
| hooks: | ||
| - id: ruff | ||
| name: lint with ruff | ||
| args: [ --fix ] | ||
| - id: ruff-format | ||
| name: format with ruff | ||
|
|
||
| - repo: https://github.com/RobertCraigie/pyright-python | ||
| rev: v1.1.406 | ||
| hooks: | ||
| - id: pyright | ||
| name: Check types with pyright | ||
| additional_dependencies: [ "pyright[nodejs]==1.1.406" ] | ||
|
|
||
| - repo: https://github.com/DavidAnson/markdownlint-cli2 | ||
| rev: v0.18.1 | ||
| hooks: | ||
| - id: markdownlint-cli2 | ||
| name: Lint markdown files | ||
| args: ["--fix"] | ||
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| 3.13 |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,92 @@ | ||
| # A part of NonVisual Desktop Access (NVDA) | ||
| # based on file from https://github.com/jcsteh/osara | ||
| # Copyright (C) 2023-2024 NV Access Limited, James Teh | ||
|
nvdaes marked this conversation as resolved.
Outdated
|
||
| # This file may be used under the terms of the GNU General Public License, version 2 or later. | ||
| # For more details see: https://www.gnu.org/licenses/gpl-2.0.html | ||
|
|
||
|
|
||
| import argparse | ||
| import os | ||
|
|
||
| import requests | ||
|
|
||
| from l10nUtil import getFiles | ||
|
|
||
| AUTH_TOKEN = os.getenv("crowdinAuthToken", "").strip() | ||
| if not AUTH_TOKEN: | ||
| raise ValueError("crowdinAuthToken environment variable not set") | ||
| PROJECT_ID = os.getenv("crowdinProjectID", "").strip() | ||
| if not PROJECT_ID: | ||
| raise ValueError("crowdinProjectID environment variable not set") | ||
|
|
||
|
|
||
| def request( | ||
| path: str, | ||
| method=requests.get, | ||
| headers: dict[str, str] | None = None, | ||
| **kwargs, | ||
| ) -> requests.Response: | ||
| if headers is None: | ||
| headers = {} | ||
| headers["Authorization"] = f"Bearer {AUTH_TOKEN}" | ||
| r = method( | ||
| f"https://api.crowdin.com/api/v2/{path}", | ||
| headers=headers, | ||
| **kwargs, | ||
| ) | ||
| # Convert errors to exceptions, but print the response before raising. | ||
| try: | ||
| r.raise_for_status() | ||
| except requests.exceptions.HTTPError: | ||
| print(r.json()) | ||
| raise | ||
| return r | ||
|
|
||
|
|
||
| def projectRequest(path: str, **kwargs) -> requests.Response: | ||
| return request(f"projects/{PROJECT_ID}/{path}", **kwargs) | ||
|
|
||
|
|
||
| def uploadSourceFile(localFilePath: str) -> None: | ||
| files = getFiles() | ||
| fn = os.path.basename(localFilePath) | ||
| crowdinFileID = files.get(fn) | ||
| print(f"Uploading {localFilePath} to Crowdin temporary storage as {fn}") | ||
| with open(localFilePath, "rb") as f: | ||
| r = request( | ||
| "storages", | ||
| method=requests.post, | ||
| headers={"Crowdin-API-FileName": fn}, | ||
| data=f, | ||
| ) | ||
| storageID = r.json()["data"]["id"] | ||
| print(f"Updating file {crowdinFileID} on Crowdin with storage ID {storageID}") | ||
| r = projectRequest( | ||
| f"files/{crowdinFileID}", | ||
| method=requests.put, | ||
| json={"storageId": storageID}, | ||
| ) | ||
| revisionId = r.json()["data"]["revisionId"] | ||
| print(f"Updated to revision {revisionId}") | ||
|
|
||
|
|
||
| def main(): | ||
| parser = argparse.ArgumentParser( | ||
| description="Syncs translations with Crowdin.", | ||
| ) | ||
| commands = parser.add_subparsers(dest="command", required=True) | ||
| uploadCommand = commands.add_parser( | ||
| "uploadSourceFile", | ||
| help="Upload a source file to Crowdin.", | ||
| ) | ||
| # uploadCommand.add_argument("crowdinFileID", type=int, help="The Crowdin file ID.") | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should this be removed?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
| uploadCommand.add_argument("localFilePath", help="The path to the local file.") | ||
| args = parser.parse_args() | ||
| if args.command == "uploadSourceFile": | ||
| uploadSourceFile(args.localFilePath) | ||
| else: | ||
| raise ValueError(f"Unknown command: {args.command}") | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| main() | ||
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| {} |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| {"translateNvdaAddonsWithCrowdin.xliff": 442, "translateNvdaAddonsWithCrowdin.pot": 444} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we do this PR first and separately?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. See PR #4