Skip to content

add CI check to block edits to translated i18n files - #442

Merged
abhinavxd merged 4 commits into
mainfrom
i18n-guard
Jul 26, 2026
Merged

add CI check to block edits to translated i18n files#442
abhinavxd merged 4 commits into
mainfrom
i18n-guard

Conversation

@abhinavxd

@abhinavxd abhinavxd commented Jul 26, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features
    • Added automated checks to detect changes to localized translation files in pull requests.
    • English source translations are excluded from this check.
    • Authorized overrides can bypass the check when needed.

@abhinavxd
abhinavxd marked this pull request as ready for review July 26, 2026 20:36
@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 2953ff93-8146-4573-84a3-dcf4f0220df8

📥 Commits

Reviewing files that changed from the base of the PR and between bcfbd45 and 1c500ed.

📒 Files selected for processing (1)
  • .github/workflows/i18n-guard.yml
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/i18n-guard.yml

📝 Walkthrough

Walkthrough

Adds a GitHub Actions workflow that checks pull request file changes and blocks edits to localized JSON files unless the allow-i18n-edit label is present.

Changes

Internationalization edit guard

Layer / File(s) Summary
Validate translated file changes
.github/workflows/i18n-guard.yml
The pull_request_target workflow checks changed i18n/*.json files, excludes i18n/en-US.json, allows labeled overrides, and fails with matching filenames when unauthorized changes are found.

Estimated code review effort: 2 (Simple) | ~10 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the new CI workflow that blocks edits to translated i18n files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch i18n-guard

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/i18n-guard.yml:
- Around line 26-29: Update the changed-file detection in the workflow step so
failures from gh api, including pagination, are not suppressed or treated as an
empty result. Preserve tolerance only for the final grep filter when no files
match, and ensure an API failure causes the workflow to fail explicitly before
the changed-files check exits successfully.
- Around line 3-5: Change the workflow trigger from pull_request to
pull_request_target while preserving the existing event types, so the i18n guard
runs from the protected base branch. Keep the job’s metadata-only behavior
unchanged and do not add checkout or execution of pull-request code.
- Around line 26-27: The file enumeration in the workflow must not rely solely
on the capped pulls/files API response. Update the logic around the gh api
pipeline to detect when the complete changed-file set cannot be reached and fail
closed, or use a complete diff source to enumerate all modified i18n JSON files
while continuing to exclude i18n/en-US.json.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 7487eb31-5ec1-4ccd-8915-3b4d86ad6c8d

📥 Commits

Reviewing files that changed from the base of the PR and between 1a0a78f and 763bcd6.

📒 Files selected for processing (1)
  • .github/workflows/i18n-guard.yml

Comment thread .github/workflows/i18n-guard.yml
Comment thread .github/workflows/i18n-guard.yml Outdated
Comment on lines +26 to +27
changed=$(gh api "repos/$REPO/pulls/$PR/files" --paginate --jq '.[].filename' \
| grep '^i18n/.*\.json$' | grep -v '^i18n/en-US\.json$' || true)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== workflow excerpt =="
if [ -f .github/workflows/i18n-guard.yml ]; then
  cat -n .github/workflows/i18n-guard.yml
else
  echo "missing .github/workflows/i18n-guard.yml"
fi

echo
echo "== PR files occurrences =="
rg -n "pulls/.*/files|changed=|enum_count|next_page|pagination|total_count" .github/workflows || true

echo
echo "== deterministic probe: gh api pagination query shape from repo =="
python3 - <<'PY'
from pathlib import Path
p=Path('.github/workflows/i18n-guard.yml')
if not p.exists():
    print('WORKFLOW_MISSING')
    raise SystemExit
s=p.read_text()
needed=[
    'gh api "repos/$REPO/pulls/$PR/files"',
    '--paginate --jq \'.[].filename\'',
    'grep -c',
    'changed_count',
    'jq ".[0]"',
    'next_page',
    '--jq ".total_count"',
]
print('contains_pr_files_api:', 'gh api "repos/$REPO/pulls/$PR/files"' in s)
print('contains_total_count:', '--jq ".total_count"' in s)
for pat in needed:
    print(f'{pat}:', pat in s)
PY

Repository: abhinavxd/libredesk

Length of output: 1936


🌐 Web query:

GitHub REST API pulls endpoint list changed files pagination 3000 files per page total_count

💡 Result:

The GitHub REST API endpoint for listing files in a pull request (GET /repos/{owner}/{repo}/pulls/{pull_number}/files) has a documented maximum limit of 3,000 files that can be returned for any single pull request [1][2]. Regarding pagination and the per_page parameter: 1. Per-Page Limit: While there is a limit of 3,000 total files per pull request, the per_page query parameter—which controls the number of results returned per individual page—is capped at 100 [1][2]. 2. Default Behavior: By default, this endpoint returns 30 files per page [1][2]. 3. Pagination Mechanism: Because the total number of files can exceed the maximum per_page limit of 100, you must use standard pagination (using the page and per_page query parameters) to retrieve all files up to the 3,000-file limit [3][2]. GitHub's API uses the link header to indicate the presence of subsequent pages, which can be followed to fetch the full set of files [3][4]. Note that if you attempt to set per_page to a value higher than 100, the API will silently clamp the value to 100, returning results without an error [5]. The total_count of files is generally not provided in the response body for this specific endpoint, as it is a paginated list; you typically navigate until no further pages are indicated by the link headers [3][4].

Citations:


🌐 Web query:

site:docs.github.com /repos/{owner}/{repo}/pulls/{pull_number}/files maximum 3000 files

💡 Result:

The GitHub REST API endpoint GET /repos/{owner}/{repo}/pulls/{pull_number}/files returns a maximum of 3,000 files for a single pull request [1][2]. Key details regarding this limit and API usage: - Pagination: While the endpoint provides a maximum of 3,000 files, these results are paginated [1]. By default, the API returns 30 files per page, but you can increase the number of results per page up to a maximum of 100 using the per_page query parameter [1][3]. - Handling Large Pull Requests: If a pull request contains more than 3,000 files, you will need to use pagination (the page query parameter) to iterate through the results [1][4]. Official documentation and guides recommend using tools like the octokit.paginate method in JavaScript to automate fetching all pages [4][5]. - Distinction from Diff Limits: Note that this file count limit is separate from diff size limits. For instance, GitHub limits the amount of diff data that can be loaded in a pull request UI to 20,000 lines or 1 MB of raw diff data per pull request, and 20,000 lines or 500 KB for any single file [6]. These UI limits are distinct from the API's ability to list the file metadata [1][6].

Citations:


Handle the pulls/files endpoint’s 3,000-file cap.

This workflow uses --paginate, but the GitHub REST endpoint itself returns at most 3,000 files per PR. If a PR has more changes, any modified i18n/* files beyond that cap can be silently missed. Fail closed when the enumeration stops before all changed files are reachable, or enumerate all modified translated files from a complete diff source.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/i18n-guard.yml around lines 26 - 27, The file enumeration
in the workflow must not rely solely on the capped pulls/files API response.
Update the logic around the gh api pipeline to detect when the complete
changed-file set cannot be reached and fail closed, or use a complete diff
source to enumerate all modified i18n JSON files while continuing to exclude
i18n/en-US.json.

Comment thread .github/workflows/i18n-guard.yml Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@i18n/de-DE.json`:
- Line 3: Restore the locale name in the "_.name" translation entry from
"Deutsch TEST" to "Deutsch" before merging.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 0f73ea75-47e5-4559-831c-13a2d8711846

📥 Commits

Reviewing files that changed from the base of the PR and between c25ad46 and bcfbd45.

📒 Files selected for processing (2)
  • .github/workflows/i18n-guard.yml
  • i18n/de-DE.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/i18n-guard.yml

Comment thread i18n/de-DE.json Outdated
@abhinavxd abhinavxd added allow-i18n-edit Allows a PR to edit Crowdin-managed translation files and removed allow-i18n-edit Allows a PR to edit Crowdin-managed translation files labels Jul 26, 2026
@abhinavxd
abhinavxd merged commit 4ec387a into main Jul 26, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant