Complete language support to all GUI tabs (#876)#877
Merged
Conversation
Wraps all user-facing string literals in the three Schedules sub-tabs (Schedule Sets, Schedules, Other Schedules) with Qt tr() calls to enable multi-language support, addressing issue #680. Files modified: - ScheduleSetInspectorView: 12 section/field labels - SchedulesView: 23 strings across ScheduleTabContent, ScheduleTabDefault, NewProfileView, DefaultScheduleDayView, SpecialScheduleDayView, ScheduleRuleView, ScheduleRulesetNameWidget, MonthView - ScheduleFileInspectorView: 15 field labels and combo box items - ScheduleDialog: 10 strings including runtime-appended values - ScheduleDayView + .hpp: 6 button/label strings; adds Q_DECLARE_TR_FUNCTIONS to 3 QGraphicsItem subclasses for tooltip tr() - ScheduleCompactInspectorView: 2 labels - ScheduleConstantInspectorView: 2 labels - ScheduleOthersController: 1 error message - ScheduleOthersView: 3 sidebar type names via QCoreApplication::translate() - MainRightColumnController: 9 sidebar nav strings via tr().toStdString() Adds Spanish translations for all new strings to OpenStudioApp_es.ts. Day-of-week single-letter buttons S/T marked unfinished pending source-level disambiguation (tr("S", "Sunday") etc.). Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
) Wraps user-facing string literals with tr() across all major tabs and adds a complete Spanish (es) translation file as proof of concept for multi-language support, addressing issue #680. Tabs covered: Site/Weather Data, Construction Sets, Materials, Schedules, Thermal Zones, Space Types, Loads, Facility, HVAC Systems, Inspector panel IDD fields, Output Variables (1051 names), Simulation Settings, Measures, Run Simulation, and Results Summary. Key patterns established: - tr() for compile-time strings in Q_OBJECT classes - QCoreApplication::translate(IDD/OutputVariables/TaxonomyCategories) for runtime strings from the OpenStudio SDK and taxonomy.xml - addItem(tr(Display), EnglishData) + currentData() for model-bound combo boxes where SDK values must stay in English - Bilingual display format for IDD fields and output variable names so engineers can cross-reference EnergyPlus documentation without switching the application language translations/OpenStudioApp_es.ts grows from ~200 to 3017 entries. New languages only require a new .ts file with no further C++ changes. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Adds Translation_GTest.cpp to the OpenStudioApp test target, covering: Translation_ts suite (no build-path dependency, uses .ts source file): - ValidXml: verifies OpenStudioApp_es.ts parses as well-formed XML - HasExpectedContexts: checks all new translation contexts are present (IDD, OutputVariables, TaxonomyCategories, SimSettingsView, RunView, etc.) - TranslationCountIsSubstantial: guards against accidental file truncation - IddContextHasEntries: IDD context has >50 field-name translations - OutputVariablesContextHasEntries: OutputVariables context has >=1000 entries - TaxonomyCategoriesContextHasEntries: taxonomy categories are present Translation_qm suite (requires compiled .qm, skipped gracefully if absent): - QmFileLoads: QTranslator::load() succeeds for OpenStudioApp_es.qm - SpanishSimSettingsStringsTranslated: spot-checks Simulation Settings labels - SpanishRunViewStringsTranslated: spot-checks Run Simulation labels - TaxonomyCategoriesTranslated: spot-checks library sidebar category names - OutputVariablesSampleTranslated: spot-checks output variable name translations - EnglishStringsReturnedWithoutTranslator: verifies English fallback when no QTranslator is installed Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
…680) - Expand language support from Spanish proof-of-concept to 18 languages: Arabic, Catalan, German, Greek, Persian, French, Hebrew, Hindi, Indonesian, Italian, Japanese, Korean, Polish, Portuguese, Turkish, Vietnamese, Simplified Chinese (new), plus Spanish - Add Portuguese, Korean, Turkish, Indonesian to Preferences > Language menu with proper QAction wiring in MainMenu.cpp/.hpp - Fix RTL layout direction: setLayoutDirection(RightToLeft) for ar/fa/he, reset to LeftToRight when switching away from RTL languages - Enable Arabic in Language menu (was commented out) - Translate ~7,000 strings per language via Claude Haiku Batches API: UI strings, IDD field names, and OutputVariable display names - Fix apply_translations counter-shift bug: use same regex pattern as extract_unfinished so XML comments and <location/> tags don't cause wrong translations to be assigned to wrong source strings - Escape HTML entities (bare <, >, & and named entities like á) in all translation files to produce valid XML for lrelease - Add batch translation scripts: translate_all_languages.py, translate_new_languages.py, retranslate_stubborn.py, recover_batches.py Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
- Wrap hardcoded strings in GeometryEditorView.cpp (Debug button) and GeometryPreviewView.cpp (Geometry Diagnostics checkbox tooltip) with tr() - Remove UTF-8 BOM from 27 inspector view .cpp files introduced by editor - Run clang-format on all modified C++ files Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Add Translation_ts.IddCoverageForAllFields GTest that loops over every IddObject in the OpenStudio IDD (via IddFactory) and verifies each field name has a corresponding source entry in the IDD translation context of OpenStudioApp_es.ts. When the SDK adds new IDD objects/fields and the .ts file is not updated, the test fails with a list of missing field names. The fix is to run add_idd_skeleton.py then translate_skeleton.py to restore coverage. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Extend IddCoverageAllLanguages (renamed from IddCoverageForAllFields) to iterate every OpenStudioApp_*.ts file in the translations directory rather than only Spanish. For each language file the test independently extracts the IDD context source strings and reports any field names missing from that specific file, so drift after an SDK update is caught per-language. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Adds translation_check.yml workflow that runs on every PR and push to master/develop. After running lupdate6 with -locations none: - git diff detects if any .ts file changed — meaning strings were added to or removed from the C++ source without the translation files being updated. - ci/check_translations.py classifies the diff: new type="unfinished" stubs (new tr() calls needing translation) vs type="obsolete" entries (tr() calls removed from source). Reports actionable fix instructions for each case and exits 1 so CI fails. If the diff is empty, all .ts files are in sync and CI passes. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
…680) Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
…th tr() - OSGridController: use tr() directly (class has Q_OBJECT, context matches) - VariablesTabView: remove translate lambda, use QCoreApplication::translate with a named ctx string to avoid redefining tr in free function scope Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Explicit include required; cannot rely on transitive pulls from other Qt headers on all build configurations. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Not part of the project source; was accidentally committed. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Bring in tr() coverage for dialogs added since the last PR #873 update: - Apply Measure Now, OSDialog buttons, Measure select prompt - Online BCL / Find Measures, Find Components category tree (tid_api.xml) - Component panel section headers and metadata row labels - Sync Measures dialog, BCL taxonomy categories - Change Default Libraries dialog - Preferences > Change External Tools dialog - Refrigeration, VRF, and other grid-view drop zone strings - Measures sidebar labels, Python CLI tooltip - Additional grid views across Facility, Spaces, Thermal Zones tabs All 19 language .ts files updated; 0 unfinished entries. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
The 'Units Conversion' Yes/No dialog shown by DView when opening an Energy+ SQL file is untranslatable via Qt's .ts system (external binary). Add tr() wrappers for both strings and translate into all 18 supported languages. The OpenStudio dialog and --ip/--si CLI forwarding are commented out pending an updated DView build (Ski90Moo/wex feat/ip-units-cli-flag); DView's own English prompt remains active in the meantime. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Documents the mandatory pipeline for adding/updating translations, including the fix_and_unvanish.py step that must follow every lupdate run. Also covers common mistakes (lambda wrapping, currentText() with model setters, unescaped ampersands). Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Wraps all user-facing string literals in the three Schedules sub-tabs (Schedule Sets, Schedules, Other Schedules) with Qt tr() calls to enable multi-language support, addressing issue #680. Files modified: - ScheduleSetInspectorView: 12 section/field labels - SchedulesView: 23 strings across ScheduleTabContent, ScheduleTabDefault, NewProfileView, DefaultScheduleDayView, SpecialScheduleDayView, ScheduleRuleView, ScheduleRulesetNameWidget, MonthView - ScheduleFileInspectorView: 15 field labels and combo box items - ScheduleDialog: 10 strings including runtime-appended values - ScheduleDayView + .hpp: 6 button/label strings; adds Q_DECLARE_TR_FUNCTIONS to 3 QGraphicsItem subclasses for tooltip tr() - ScheduleCompactInspectorView: 2 labels - ScheduleConstantInspectorView: 2 labels - ScheduleOthersController: 1 error message - ScheduleOthersView: 3 sidebar type names via QCoreApplication::translate() - MainRightColumnController: 9 sidebar nav strings via tr().toStdString() Adds Spanish translations for all new strings to OpenStudioApp_es.ts. Day-of-week single-letter buttons S/T marked unfinished pending source-level disambiguation (tr("S", "Sunday") etc.). Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
) Wraps user-facing string literals with tr() across all major tabs and adds a complete Spanish (es) translation file as proof of concept for multi-language support, addressing issue #680. Tabs covered: Site/Weather Data, Construction Sets, Materials, Schedules, Thermal Zones, Space Types, Loads, Facility, HVAC Systems, Inspector panel IDD fields, Output Variables (1051 names), Simulation Settings, Measures, Run Simulation, and Results Summary. Key patterns established: - tr() for compile-time strings in Q_OBJECT classes - QCoreApplication::translate(IDD/OutputVariables/TaxonomyCategories) for runtime strings from the OpenStudio SDK and taxonomy.xml - addItem(tr(Display), EnglishData) + currentData() for model-bound combo boxes where SDK values must stay in English - Bilingual display format for IDD fields and output variable names so engineers can cross-reference EnergyPlus documentation without switching the application language translations/OpenStudioApp_es.ts grows from ~200 to 3017 entries. New languages only require a new .ts file with no further C++ changes. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Adds Translation_GTest.cpp to the OpenStudioApp test target, covering: Translation_ts suite (no build-path dependency, uses .ts source file): - ValidXml: verifies OpenStudioApp_es.ts parses as well-formed XML - HasExpectedContexts: checks all new translation contexts are present (IDD, OutputVariables, TaxonomyCategories, SimSettingsView, RunView, etc.) - TranslationCountIsSubstantial: guards against accidental file truncation - IddContextHasEntries: IDD context has >50 field-name translations - OutputVariablesContextHasEntries: OutputVariables context has >=1000 entries - TaxonomyCategoriesContextHasEntries: taxonomy categories are present Translation_qm suite (requires compiled .qm, skipped gracefully if absent): - QmFileLoads: QTranslator::load() succeeds for OpenStudioApp_es.qm - SpanishSimSettingsStringsTranslated: spot-checks Simulation Settings labels - SpanishRunViewStringsTranslated: spot-checks Run Simulation labels - TaxonomyCategoriesTranslated: spot-checks library sidebar category names - OutputVariablesSampleTranslated: spot-checks output variable name translations - EnglishStringsReturnedWithoutTranslator: verifies English fallback when no QTranslator is installed Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
…680) - Expand language support from Spanish proof-of-concept to 18 languages: Arabic, Catalan, German, Greek, Persian, French, Hebrew, Hindi, Indonesian, Italian, Japanese, Korean, Polish, Portuguese, Turkish, Vietnamese, Simplified Chinese (new), plus Spanish - Add Portuguese, Korean, Turkish, Indonesian to Preferences > Language menu with proper QAction wiring in MainMenu.cpp/.hpp - Fix RTL layout direction: setLayoutDirection(RightToLeft) for ar/fa/he, reset to LeftToRight when switching away from RTL languages - Enable Arabic in Language menu (was commented out) - Translate ~7,000 strings per language via Claude Haiku Batches API: UI strings, IDD field names, and OutputVariable display names - Fix apply_translations counter-shift bug: use same regex pattern as extract_unfinished so XML comments and <location/> tags don't cause wrong translations to be assigned to wrong source strings - Escape HTML entities (bare <, >, & and named entities like á) in all translation files to produce valid XML for lrelease - Add batch translation scripts: translate_all_languages.py, translate_new_languages.py, retranslate_stubborn.py, recover_batches.py Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
- Wrap hardcoded strings in GeometryEditorView.cpp (Debug button) and GeometryPreviewView.cpp (Geometry Diagnostics checkbox tooltip) with tr() - Remove UTF-8 BOM from 27 inspector view .cpp files introduced by editor - Run clang-format on all modified C++ files Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Add Translation_ts.IddCoverageForAllFields GTest that loops over every IddObject in the OpenStudio IDD (via IddFactory) and verifies each field name has a corresponding source entry in the IDD translation context of OpenStudioApp_es.ts. When the SDK adds new IDD objects/fields and the .ts file is not updated, the test fails with a list of missing field names. The fix is to run add_idd_skeleton.py then translate_skeleton.py to restore coverage. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Not part of the project source; was accidentally committed. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Bring in tr() coverage for dialogs added since the last PR #873 update: - Apply Measure Now, OSDialog buttons, Measure select prompt - Online BCL / Find Measures, Find Components category tree (tid_api.xml) - Component panel section headers and metadata row labels - Sync Measures dialog, BCL taxonomy categories - Change Default Libraries dialog - Preferences > Change External Tools dialog - Refrigeration, VRF, and other grid-view drop zone strings - Measures sidebar labels, Python CLI tooltip - Additional grid views across Facility, Spaces, Thermal Zones tabs All 19 language .ts files updated; 0 unfinished entries. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
The 'Units Conversion' Yes/No dialog shown by DView when opening an Energy+ SQL file is untranslatable via Qt's .ts system (external binary). Add tr() wrappers for both strings and translate into all 18 supported languages. The OpenStudio dialog and --ip/--si CLI forwarding are commented out pending an updated DView build (Ski90Moo/wex feat/ip-units-cli-flag); DView's own English prompt remains active in the meantime. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Documents the mandatory pipeline for adding/updating translations, including the fix_and_unvanish.py step that must follow every lupdate run. Also covers common mistakes (lambda wrapping, currentText() with model setters, unescaped ampersands). Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
In Qt 6 the QMenuBar inherits the parent QMainWindow dark background (#2C3233) instead of using the native platform style. Add explicit QMenuBar rules alongside the existing MainWindow stylesheet so the menu bar stays white with black text regardless of locale or restart. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
In Qt 6 the QMenuBar inherits the parent QMainWindow dark background (#2C3233) instead of using the native platform style. Add explicit QMenuBar rules alongside the existing MainWindow stylesheet so the menu bar stays white with black text regardless of locale or restart. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
81c1241 to
dbd5fd5
Compare
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
|
Fixed the Clang Format failure — switched to |
Add the six Python scripts referenced in TRANSLATION_WORKFLOW.md and the IddCoverageAllLanguages test but absent from the PR: - fix_and_unvanish.py — un-vanish translated entries; promote unfinished - translate_all_languages.py — batch-translate new strings into all 18 languages - retranslate_stubborn.py — re-translate remaining empty entries - recover_batches.py — re-poll batch IDs after network failure - add_idd_skeleton.py — add missing IDD field names as unfinished stubs - translate_skeleton.py — translate IDD context stubs via Claude batch API Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
- Add OpenStudioApp_{id,ko,pt,tr}.ts to qt6_add_translations TS_FILES so
the .qm files are compiled and deployed on all platforms, not just when
pre-built .qm files happen to be present in the source tree.
- Add post-build copy commands for Qt system translations (qt_ko, qt_tr,
qt_pt_BR, qtbase_*) and WebEngine pak files for the four new languages.
Indonesian follows the same commented-out pattern as Hindi/Vietnamese/Greek
since Qt does not ship qt_id / qtbase_id translations.
- Remove stale moc_*.cpp entry from .gitignore; Qt 6 + CMake always
generates moc files in the build directory, never in the source tree.
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
IDD field display (InspectorGadget.cpp): - Replace 'Translation (English)' inline format with HTML: translated name on first line, English original in small gray italics on second line. Non-English speakers can cross-reference EnergyPlus docs without switching languages; tooltip approach was rejected as cursor-precision-dependent. Whitespace restoration (fix_and_unvanish.py + all .ts files): - Add Step 4 to fix_and_unvanish.py: restore leading/trailing spaces in translations to match source strings (stripped by .strip() in translation scripts). Fixes ~6900 Qt Linguist whitespace-mismatch warnings. Newline fixes (all .ts files): - For LoopLibraryDialog strings: remove hard \n breaks from both C++ source and all translations now that the dialog is resizable. - For all other \n-containing strings (grid headers, drop zones, etc.): apply proportional-position insertion to restore missing \n in translations. LoopLibraryDialog resize (LoopLibraryDialog.cpp): - Replace setFixedSize(280,584) with setMinimumSize(280,400) + setSizeGripEnabled. - Add setWordWrap(true) and remove Qt::AlignLeft from addWidget so label stretches to full item width and reflows correctly on resize. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Per jmarrec review: add a callout at the top noting this doc covers the AI-assisted bootstrap pipeline, and linking to the wiki for the preferred human-translation workflow via Qt Linguist. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
translations/CMakeLists.txt line 151 was copying vi.pak (Vietnamese) instead of de.pak. Copy-paste error from the Vietnamese section directly above it. Audited all 18 language blocks — only mismatch. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
- fix_and_unvanish.py: add Step 5 to escape bare XML chars (<, >, &) in finished translation text, preventing lrelease parse errors - translate_all_languages.py: add --lang and --skip-contexts CLI args; extract_unfinished now marks skipped-context entries so IDs stay stable - add_language_to_menu.py: new script that automates all 5 C++ touch points when wiring a new language into MainMenu.hpp/.cpp Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Add a six-step "Adding a new language" section covering the C++ menu wiring script, CMakeLists.txt entries, translate_all_languages.py update, and the standard pipeline. Expand the helper scripts table with add_language_to_menu.py. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Apply fix_and_unvanish.py Step 5 retroactively: escape bare > characters as > in finished translation text for consistency. Bare < characters (the hard XML error) were not present in the existing 18 files, but > is normalized here for correctness and to prevent future lrelease surprises. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Introduces two new scripts for improving machine translations of EnergyPlus output variable names using BigLadder I/O Reference context: - scrape_output_var_definitions.py: crawls all 52 BigLadder I/O Reference group pages (h3/h4/h5 headings) to extract variable definitions and units into output_var_definitions.json (2,733 entries) - retranslate_output_vars.py: re-translates the OutputVariables context in .ts files using definition-aware prompts, canonical category/sub-category splitting, and a three-level Zone hierarchy (Zone: SubCat: Measurement) Translation improvements for ES and FR: - Category:Measurement structure prevents word-order mangling across the category boundary - ~51% of variables receive full definition context from the I/O Reference - Template fallback covers fuel-type variants (Boiler <Fuel Type>, etc.) - Zone variables use three-level prompting for consistency Also adds output_var_definitions.json, output_vars_comparison_v3.csv, and output_var_zone_splits.csv as reference artifacts for quality review. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Move all helper scripts, data files, and comparison CSVs from the repo root into translations/. Delete 8 superseded one-shot scripts. Add three new retranslate scripts (gui_strings, idd_fields, output_vars) with a --mode option (unfinished|all) so finished human translations are never overwritten by default. Add Part 3 (IDD fields) to update_comparison_csvs.py. Standardise CSV names (drop version suffix, rename other_contexts → gui_comparison). Update TRANSLATION_WORKFLOW.md throughout. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
…e translations Surgically restore 133 ES and 191 FR human-provided translations from origin/develop that had been overwritten by retranslate scripts run without the --mode unfinished guard. All machine-translated slots retain the improved definition-aware translations. Also fixes a pre-existing bug where the FR file had the Spanish text for "Purge unused objects". Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Retranslate ar, ca, de, el, fa, he, hi, id, it, ja, ko, pl, pt, tr, vi, and zh_CN end-to-end with the definition-aware IDD/OutputVariables/GUI pipeline from ac13885, while preserving every existing human translation verbatim. es and fr get the same XML-escaping and trailing-whitespace normalization that fix_and_unvanish.py applies elsewhere. This represents a significant quality improvement (translation drift) over the prior machine translations, which lacked field-definition and category context. Fix a regex crossing bug in extract_unfinished/apply_translations: <source>([\s\S]+?)</source> could backtrack across an already-translated message into the next <source>/<translation> pair. This silently dropped ~110 entries per language (in the 11 languages with pre-existing translations) from the batch entirely, or translated them but never applied the result. Switch to <source>([^<]+)</source> -- .ts source text is XML-escaped and can never contain a literal '<', so the match can no longer cross message boundaries. Also stop apply_translations' tag-stripping step from emptying out translations that are themselves bracketed placeholders (e.g. "<New Profile>" -> "<Nuevo Perfil>"), which had left one entry stuck in ar/id/ko/pt/tr. Add recover_batch.py, a general-purpose --lang/--batch-id tool for applying results from a batch that timed out or failed to download, replacing the one-off recover_*.py scripts written during this effort. Document it in TRANSLATION_WORKFLOW.md with a new "Recovering a stuck or failed batch" section, and point translate_all_languages.py's polling-timeout message at it. All 18 .ts files now show 0 vanished / 0 unfinished entries after fix_and_unvanish.py, and `cmake --build . --config Release` succeeds with the regenerated .qm files. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
# Conflicts: # src/openstudio_lib/ScheduleFileInspectorView.cpp
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
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
Duplicates #873 from @Ski90Moo on internal branch for CI