Skip to content

Translation tracker: auto close issue on PR merged and closed and translation coverage - #1582

Draft
aashishpanthi wants to merge 557 commits into
processing:mainfrom
aashishpanthi:feature/translation-tracker/auto-close-issue
Draft

aashishpanthi wants to merge 557 commits into
processing:mainfrom
aashishpanthi:feature/translation-tracker/auto-close-issue

Conversation

@aashishpanthi

@aashishpanthi aashishpanthi commented Aug 23, 2026 •

Copy link
Copy Markdown
Member

Summary

Extends the translation tracker with:

  1. Auto-close – When a translation PR is merged, find referenced tracker issues, verify the expected file was added/modified (not deleted/renamed), strike that language, remove its lang-* label, and close the issue when nothing remains.
  2. Translation coverage – Publish a public coverage report at public/translation-status/coverage.json (served as /translation-status/coverage.json).

Addresses #1404.

Auto-close issue

How an issue is found

Relying on Resolves #123 did not worked well with real contributors: most translation PRs either use no linking keyword or mention the issue somewhere other than the body. So any #123 is treated as a candidate, and it is looked for in:

  • the PR title and body
  • review summaries (maintainers can/do write "this handles #123" during review)
  • issues that cross-reference the PR from their own thread
  • pasted https://github.com/<owner>/<repo>/issues/123 links

Also, comments written by bots are ignored, so the tracker's own automation cannot feed itself.

How false positives are avoided

Matching every #123 is deliberately greedy, so candidates are filtered:

  • fenced code blocks and inline code spans are stripped first, which removes most hex colors and code samples
  • owner/repo#123 cross-repo references and #123abc are not matched; numbers are capped at five digits because color codes are six digits and we are in four digits, we'll reach six digits in years (needs attention)
  • the PR's own number is skipped
  • each remaining candidate must exist, must not be a pull request, and must carry the needs translation label

How an issue is updated

Which languages a PR translated is derived from its changed file paths, for example src/content/examples/es/... means Spanish. For each such language, the action removes the lang-<code> label and strikes that language's line in the issue body. The issue is closed only when no lang-* labels are left.

One tracker issue often covers several languages for the same English file, which creates a wrinkle: GitHub closes an issue natively the instant a PR saying Fixes #123 is merged, even when only one of four languages was done. The action detects this and reopens the issue, leaving a comment naming the languages still working.

Translation coverage

  • Workflow: translation-coverage.yml — runs on push to main for content changes, or via Actions → Translation Coverage → Run workflow.
  • Script: .github/actions/translation-tracker/coverage.js — filesystem-only scan (present / missing / stub). Andd excludes reference.
  • Commits coverage.json as a public file for the visualization.
  • Manual inputs: languages, content_types which can be dispatched from web.

Test plan

  • Merge a fork PR that updates the correct translation file and references a tracker issue → label removed, line struck, issue closed/reopened correctly. See here
  • Run Translation Coverage from the Actions UI with defaults → coverage.json updates quickly. See here
  • Confirm /translation-status/coverage.json is publicly reachable after deploy.

coseeian and others added 30 commits February 1, 2026 17:04
feat: add title attributes to all iframes for accessibility
…-doc

fix: correct circle() diameter explanation in Get Started tutorial
fix: restore focus after search submission (processing#914)
feat: add visually invisble h1 to search result page
feat: Add alt text to CC BY-NC-SA license badge in ExampleLayout
…nt-path

replace deprecated dirent.path with dirent.parentPath (on main). fixes processing#1111
…ation

chore: add missing Hindi translations for homepage & UI elements
fix: inconsistent paths and backticks in technical_overview.md file
Also added some logging so it's clear which repo & branch are being considered / cloned
Improve code block contrast with GitHub Light High Contrast theme
@aashishpanthi

Copy link
Copy Markdown
Member Author

Note: This branches off the stub-file-generation PR. So, #1473 should be merged first, then this.

name: Translation Auto-Close

on:
pull_request:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Hi @aashishpanthi , I see one blocker here for which I'm not very sure.

For any PR opened from a fork (which is how virtually all external translation contributors submit), GitHub downgrades GITHUB_TOKEN to read-only regardless of the permissions: block. This workflow needs issues: write to remove labels, edit the body, comment, and close/reopen, all of those API calls (removeLabel, issues.update, createComment) will return 403 for fork PRs.

The whole motivation of the PR ("real contributors" not using linking keywords) implies fork-based PRs, so as written the feature might work only for maintainers pushing branches inside the repo.

Can we test this on a fork?

cc: @ksen0 do you have any views here?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Sorry for the very delayed response, but I created a new GitHub account just to try the new changes. As you can see, aap009#15

Here, the write on issues is working. In the workflow file, I changed the workflow trigger from pull_request to pull_request_target. Exactly this.

Let me know if any problems arise.

const { getLanguageDisplayName, getTranslationPath } = require('./utils');

// List all files changed in a merged PR (paginated).
async function listPullRequestFiles(octokit, owner, repo, pullNumber) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This function returns every file including status: "removed"/"renamed", and neither identifyLanguagesFromFiles nor the verifiedLanguages filter checks status:

const verifiedLanguages = languages.filter((lang) => {
const paths = expectedPaths.get(lang);
if (!paths || paths.length === 0) return false;
return paths.some((p) => changedFileNames.includes(p)); // matches removed files too
});

A PR that deletes src/content/examples/es/foo.mdx would strike Spanish, remove lang-es, and potentially close the tracker issue - the opposite of the truth. Filter to file.status === 'added' || 'modified' (or exclude removed) before deriving languages and verifying paths.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I resolved it, now we check if the file was updated, added, or deleted.

@aashishpanthi
aashishpanthi changed the base branch from v1 to main October 19, 2026 04:57
@aashishpanthi

Copy link
Copy Markdown
Member Author

Also, latest update:

I have added the translation coverage to this PR. A detailed description is found above in PR description. But it can be dispatched from GitHub Actions. See one here.

This is what the dispatch looks like:
image

@aashishpanthi aashishpanthi changed the title Translation tracker: auto close issue on PR merged and closed Translation tracker: auto close issue on PR merged and closed and translation coverage Oct 20, 2026

This branch has not been deployed

No deployments
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.