From ff4533c767af78fd52b5f6d62f8a4770858a51ec Mon Sep 17 00:00:00 2001 From: Shahar Epstein <60007259+shahar1@users.noreply.github.com> Date: Sun, 31 Aug 2025 21:34:22 +0300 Subject: [PATCH 1/5] Implement default language (English) freeze pre-commit --- .pre-commit-config.yaml | 12 ++++ .../ci/prek/check_default_language_freeze.py | 57 +++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100755 scripts/ci/prek/check_default_language_freeze.py diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index cea777e49ed76..dc394cd09f98c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1456,6 +1456,18 @@ repos: files: ^airflow-core/src/airflow/ui/public/i18n/locales/.*\.json$ entry: ./scripts/ci/prek/check_i18n_json.py pass_filenames: false + - id: check-en-language-freeze + name: Check for Default language (English) freeze + description: Prevent changes to English translation files during the language freeze period (typically around release time; time is measured in UTC) + language: python + entry: ./scripts/ci/prek/check_default_language_freeze.py + args: + - --freeze-start-date + - "2025-09-01" + - --freeze-end-date + - "2025-09-09" + files: ^airflow-core/src/airflow/ui/public/i18n/locales/en/.* + pass_filenames: true - id: check-provider-yaml-valid name: Validate provider.yaml files entry: ./scripts/ci/prek/check_provider_yaml_files.py diff --git a/scripts/ci/prek/check_default_language_freeze.py b/scripts/ci/prek/check_default_language_freeze.py new file mode 100755 index 0000000000000..9a401d1a75c55 --- /dev/null +++ b/scripts/ci/prek/check_default_language_freeze.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +from __future__ import annotations + +import argparse +import sys +from datetime import datetime + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + description="Check for language freeze period and prevent changes to specified files." + ) + parser.add_argument("--freeze-start-date", required=True, help="Start date of the freeze (YYYY-MM-DD)") + parser.add_argument("--freeze-end-date", required=True, help="End date of the freeze (YYYY-MM-DD)") + parser.add_argument("files", nargs="*", help="Files to check.") + args = parser.parse_args() + + freeze_start = None + freeze_end = None + try: + freeze_start = datetime.strptime(args.freeze_start_date, "%Y-%m-%d").date() + freeze_end = datetime.strptime(args.freeze_end_date, "%Y-%m-%d").date() + except ValueError as e: + print(f"Error: Invalid date format in pre-commit config. {e}", file=sys.stderr) + sys.exit(1) + + today = datetime.now(timezone.utc).date() + + if freeze_start <= today <= freeze_end: + if args.files: + print( + f"Error: English language freeze is active from {args.freeze_start_date} to " + f"{args.freeze_end_date}.", + file=sys.stderr, + ) + print("Changes to English translation files are not allowed during this period.", file=sys.stderr) + print("The following files are affected:", file=sys.stderr) + for file_path in args.files: + print(f" - {file_path}", file=sys.stderr) + sys.exit(1) + + sys.exit(0) From 209ad75cb3d44d89a036c12c5517e9dbc3d8d432 Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Mon, 1 Sep 2025 09:16:59 +0800 Subject: [PATCH 2/5] fix: fix missing import --- scripts/ci/prek/check_default_language_freeze.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/ci/prek/check_default_language_freeze.py b/scripts/ci/prek/check_default_language_freeze.py index 9a401d1a75c55..68df79ee3eac4 100755 --- a/scripts/ci/prek/check_default_language_freeze.py +++ b/scripts/ci/prek/check_default_language_freeze.py @@ -19,7 +19,7 @@ import argparse import sys -from datetime import datetime +from datetime import datetime, timezone if __name__ == "__main__": parser = argparse.ArgumentParser( From 9db94250cfbb83a968daebec5132cdd11c67ef60 Mon Sep 17 00:00:00 2001 From: Shahar Epstein <60007259+shahar1@users.noreply.github.com> Date: Mon, 1 Sep 2025 07:29:01 +0300 Subject: [PATCH 3/5] Add git diff --- scripts/ci/prek/check_default_language_freeze.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/scripts/ci/prek/check_default_language_freeze.py b/scripts/ci/prek/check_default_language_freeze.py index 68df79ee3eac4..5df95b9cb7305 100755 --- a/scripts/ci/prek/check_default_language_freeze.py +++ b/scripts/ci/prek/check_default_language_freeze.py @@ -20,6 +20,7 @@ import argparse import sys from datetime import datetime, timezone +from subprocess import run if __name__ == "__main__": parser = argparse.ArgumentParser( @@ -42,15 +43,18 @@ today = datetime.now(timezone.utc).date() if freeze_start <= today <= freeze_end: - if args.files: + changed_files = [ + f for f in args.files if run(["git", "diff", "--cached", "--quiet", "--", f]).returncode != 0 + ] + if changed_files: print( f"Error: English language freeze is active from {args.freeze_start_date} to " f"{args.freeze_end_date}.", file=sys.stderr, ) print("Changes to English translation files are not allowed during this period.", file=sys.stderr) - print("The following files are affected:", file=sys.stderr) - for file_path in args.files: + print("The following files have staged changes:", file=sys.stderr) + for file_path in changed_files: print(f" - {file_path}", file=sys.stderr) sys.exit(1) From 8b6a6e2a9c9b3d008e3235126d3029521cbe3908 Mon Sep 17 00:00:00 2001 From: Shahar Epstein <60007259+shahar1@users.noreply.github.com> Date: Mon, 1 Sep 2025 07:50:00 +0300 Subject: [PATCH 4/5] Create freeze exemptions --- .pre-commit-config.yaml | 1 + .../public/i18n/locales/en/_freeze_exemptions.json | 12 ++++++++++++ dev/i18n/check_translations_completeness.py | 7 ++++++- 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 airflow-core/src/airflow/ui/public/i18n/locales/en/_freeze_exemptions.json diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index dc394cd09f98c..a8dd47fd5bad7 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1467,6 +1467,7 @@ repos: - --freeze-end-date - "2025-09-09" files: ^airflow-core/src/airflow/ui/public/i18n/locales/en/.* + exclude: ^airflow-core/src/airflow/ui/public/i18n/locales/en/_freeze_exemptions\.json.* pass_filenames: true - id: check-provider-yaml-valid name: Validate provider.yaml files diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/en/_freeze_exemptions.json b/airflow-core/src/airflow/ui/public/i18n/locales/en/_freeze_exemptions.json new file mode 100644 index 0000000000000..43fcce7b0801f --- /dev/null +++ b/airflow-core/src/airflow/ui/public/i18n/locales/en/_freeze_exemptions.json @@ -0,0 +1,12 @@ +{ + "admin": {}, + "assets": {}, + "browse": {}, + "common": {}, + "components": {}, + "dag": {}, + "dags": {}, + "dashboard": {}, + "hitl": {}, + "tasks": {} +} diff --git a/dev/i18n/check_translations_completeness.py b/dev/i18n/check_translations_completeness.py index 1ca6907423fc1..1435a829bc1c9 100755 --- a/dev/i18n/check_translations_completeness.py +++ b/dev/i18n/check_translations_completeness.py @@ -124,7 +124,12 @@ def expand_plural_keys(keys: set[str], lang: str) -> set[str]: def get_locale_files() -> list[LocaleFiles]: return [ LocaleFiles( - locale=locale_dir.name, files=[f.name for f in locale_dir.iterdir() if f.suffix == ".json"] + locale=locale_dir.name, + files=[ + f.name + for f in locale_dir.iterdir() + if f.suffix == ".json" and f.name != "_freeze_exemptions.json" + ], ) for locale_dir in LOCALES_DIR.iterdir() if locale_dir.is_dir() From 0d4efab511e94c50670d4d8005f5c4f698fc64fb Mon Sep 17 00:00:00 2001 From: Shahar Epstein <60007259+shahar1@users.noreply.github.com> Date: Mon, 1 Sep 2025 08:30:25 +0300 Subject: [PATCH 5/5] Change to AoE --- scripts/ci/prek/check_default_language_freeze.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/scripts/ci/prek/check_default_language_freeze.py b/scripts/ci/prek/check_default_language_freeze.py index 5df95b9cb7305..10b4b4acd366f 100755 --- a/scripts/ci/prek/check_default_language_freeze.py +++ b/scripts/ci/prek/check_default_language_freeze.py @@ -19,7 +19,7 @@ import argparse import sys -from datetime import datetime, timezone +from datetime import datetime, timedelta, timezone from subprocess import run if __name__ == "__main__": @@ -40,7 +40,7 @@ print(f"Error: Invalid date format in pre-commit config. {e}", file=sys.stderr) sys.exit(1) - today = datetime.now(timezone.utc).date() + today = datetime.now(timezone(timedelta(hours=-12))).date() if freeze_start <= today <= freeze_end: changed_files = [ @@ -52,7 +52,14 @@ f"{args.freeze_end_date}.", file=sys.stderr, ) - print("Changes to English translation files are not allowed during this period.", file=sys.stderr) + print( + "Changes to English translation files (except for _freeze_exemptions.json) are not allowed during this period.", + file=sys.stderr, + ) + print( + "You may instead add the changes to _freeze_exemptions.json, and by the end of the freeze period, we will merge them back to the original files.", + file=sys.stderr, + ) print("The following files have staged changes:", file=sys.stderr) for file_path in changed_files: print(f" - {file_path}", file=sys.stderr)