Browse / github.com/storytold/pdfcraft / patch
ci: put the translation gaps report in the job summary
ci: put the translation gaps report in the job summary `cargo xtask i18n-report` already runs as a step of `cargo xtask ci`, but its output was buried in the job log. Under GitHub Actions it now also appends the report to `GITHUB_STEP_SUMMARY` as a "Translation gaps" section. Best effort: a missing variable, an unwritable summary file or an empty report is ignored, so it never fails the build. No new CI step or workflow. Checked: no open or closed PR covers this; `cargo fmt --check` and `cargo clippy -p xtask -D warnings` pass locally. I did not run the report in Actions here; the fork's CI run will show the summary. <!-- This is an auto-genera
- Status
- open
- Score
- 0.00
- Adopters
- 0 other operators
- Author
- Harrison-Booth (imported from pull request #5057, open)
- Base
9e90b2a54d6250465ba3d11a6eb0b13f3b690381- Size
- +10 −3 in 2 files
- Review
- pending
- Shared
- 2026-10-28
- Id
bed89c6f4c6dc734a6107222
How it went
No other operator has reported using it yet.
Diff
raw · docs/localization.md xtask/src/gates.rs
@@ -67,7 +67,7 @@ PdfCraft uses the same system as PhotoCraft (`crates/ui-egui/src/i18n/`): - Strings in the code stay in English and serve as lookup keys. At draw time, `tl!("Save")` returns the text in the current language, and falls back to English when there is no entry. - Each language has a catalog, `crates/ui-egui/src/i18n/<code>.tsv`, with one entry per line: `context<TAB>English<TAB>translation`. An empty context marks a plain string. `@id` keys an entry by command id (for example `file.saveAs`), so one menu item can read differently from another with the same English label. `@plural` holds plural forms. Any other context disambiguates an English word with several meanings (`tl_ctx!` in UI code, for example the signature pad's "Type" button against the "Type" column). The header of `ja.tsv` documents the format and escapes. - Placeholders (`{name}`) must appear in both columns. A trailing `…` must be kept. `i18n::fmt` fills placeholders in one pass, so a value such as a file name containing `{n}` is inserted as written.-- A missing entry never fails a build or a test: that string shows in English. `cargo xtask i18n-report`, a step of `cargo xtask ci`, prints for each language how many strings it has no translation for and the first few. It counts every command, All tools label, literal passed to `tl!` or `i18n::t` in the UI source, engine wording (below) and key of the bundled catalogs, so a new English string shows up there until each catalog has it.+- A missing entry never fails a build or a test: that string shows in English. `cargo xtask i18n-report`, a step of `cargo xtask ci`, prints for each language how many strings it has no translation for and the first few (under GitHub Actions the same report also lands in the job summary). It counts every command, All tools label, literal passed to `tl!` or `i18n::t` in the UI source, engine wording (below) and key of the bundled catalogs, so a new English string shows up there until each catalog has it. - Catalogs are validated strictly: unknown escapes, unknown `@` contexts, placeholder or ellipsis mismatches, wrong plural form counts and duplicates are errors. The tests require the bundled catalogs to have none; at run time a bad line is skipped (and logged) and that string shows in English. - Each `.tsv` has an `ATTRIBUTION.toml` entry with `kind = "translation"` (title, author, source, licence), checked by `cargo xtask assets`. Catalogs are project files under the project licence, so the entry has no `sha256` and editing a catalog doesn't touch `ATTRIBUTION.toml`; git history records their provenance. - Translations are clean-room: write them from the meaning of the English text, never from another product's string tables.@@ -133,7 +133,8 @@ pub fn ci(_: &[String]) -> anyhow::Result<()> { /// `cargo xtask i18n-report`: the strings each interface language has no translation for, as /// counts and the first few keys, from the UI crate's `translation_gaps_report` test. It always-/// passes: a missing string shows in English. `--workspace` runs the test from the workspace+/// passes: a missing string shows in English. Under GitHub Actions the report is also appended to+/// the job summary (`GITHUB_STEP_SUMMARY`). `--workspace` runs the test from the workspace /// test build, which `xtask ci` has just made; without it only the UI crate is built. pub fn i18n_report(args: &[String]) -> anyhow::Result<()> { const TEST: &str = "i18n::tests::translation_gaps_report";@@ -155,9 +156,15 @@ pub fn i18n_report(args: &[String]) -> anyhow::Result<()> { if report.is_empty() { println!("i18n-report: no report (cargo test exited with {})", out.status); }- for line in report {+ for line in &report { println!("{line}"); }+ // Under GitHub Actions, also show the report in the job summary. Best effort: never fails the build.+ if let (Some(path), false) = (std::env::var_os("GITHUB_STEP_SUMMARY"), report.is_empty()) {+ use std::io::Write;+ let text = format!("### Translation gaps\n\n```\n{}\n```\n", report.join("\n"));+ let _ = std::fs::OpenOptions::new().append(true).create(true).open(path).and_then(|mut f| f.write_all(text.as_bytes()));+ } Ok(()) }