DEVX-152: fix: remove dead translation keys and add missing one
CI / validate (pull_request) Successful in 50s
CI / auto-merge (pull_request) Failing after 11s

Co-authored-by: emil User <emil.simeonov@tutanota.com>
This commit is contained in:
2026-08-09 03:04:46 +02:00
committed by emil
parent 5cacbdec09
commit 74ee1830e5
12 changed files with 190 additions and 131 deletions
-1
View File
@@ -52,7 +52,6 @@ REQUIRED_SCRIPTS = [
"detect_release_commit.py",
"push_badges.py",
"distribute_molecule.py",
"molecule_ci_guard.py",
"validate_commit_msg.py",
]
+51 -7
View File
@@ -1,10 +1,9 @@
#!/usr/bin/env python3
"""Run integration tests with cross-runner failure detection.
Wraps ``pytest`` with the same Gitea API polling mechanism used by
``molecule_ci_guard``. If any other integration-tests matrix runner
reports failure, the current pytest subprocess is killed and this runner
exits early with code 1.
Wraps ``pytest`` with Gitea API polling. If any other integration-tests
matrix runner reports failure, the current pytest subprocess is killed
and this runner exits early with code 1.
Usage::
@@ -35,17 +34,62 @@ import threading
import time
import click
import requests
from devx.config import REPO_NAME, REPO_OWNER
from devx.i18n import _
from devx.molecule.molecule_ci_guard import (
poll_for_other_failures,
)
from devx.tokens import get_ci_token
POLL_INTERVAL = 10
def get_running_jobs(gitea_url: str, owner: str, repo: str, token: str, run_id: int) -> list[dict]:
"""Return jobs for the given workflow run."""
url = f"{gitea_url}/api/v1/repos/{owner}/{repo}/actions/runs/{run_id}/jobs"
headers = {"Authorization": f"token {token}"}
response = requests.get(url, headers=headers, timeout=30)
response.raise_for_status()
data = response.json()
return data.get("jobs", [])
def any_other_runner_failed(jobs: list[dict], current_job_name: str, current_index: int) -> bool:
"""Return True if any other matrix job has failed."""
for job in jobs:
name = job.get("name", "")
if not name.startswith(current_job_name):
continue
if name == f"{current_job_name} ({current_index})" or name == current_job_name:
continue
if job.get("conclusion") == "failure":
return True
return False
def poll_for_other_failures(
gitea_url: str,
owner: str,
repo: str,
token: str,
run_id: int,
job_name: str,
current_index: int,
stop_event: threading.Event,
failed_event: threading.Event,
) -> None:
"""Background thread: poll API and signal if another runner fails."""
while not stop_event.is_set():
try:
jobs = get_running_jobs(gitea_url, owner, repo, token, run_id)
if any_other_runner_failed(jobs, job_name, current_index):
click.echo(_("Another runner failed. Stopping this runner early."))
failed_event.set()
return
except requests.RequestException as exc:
click.echo(_("API poll warning: {exc}", exc=exc))
stop_event.wait(POLL_INTERVAL)
@click.command(context_settings={"ignore_unknown_options": True})
@click.argument("pytest_args", nargs=-1, type=click.UNPROCESSED, required=True)
def cli(pytest_args: tuple[str, ...]) -> None:
-7
View File
@@ -301,13 +301,6 @@ def molecule_discover_runners(args: tuple[str, ...]) -> None:
_run_module("devx.molecule.discover_runners", list(args))
@molecule.command("guard")
@click.argument("args", nargs=-1)
def molecule_guard(args: tuple[str, ...]) -> None:
"""Run molecule tests sequentially with CI failure polling."""
_run_module("devx.molecule.molecule_ci_guard", list(args))
@molecule.command("all")
@click.argument("args", nargs=-1)
def molecule_all(args: tuple[str, ...]) -> None:
+7 -47
View File
@@ -783,14 +783,6 @@
"ru": "Additional directory to scan (default: scripts, tests). Can be repeated.",
"zh": "Additional directory to scan (default: scripts, tests). Can be repeated."
},
"All molecule tests passed.": {
"bg": "All molecule tests passed.",
"de": "All molecule tests passed.",
"en": "All molecule tests passed.",
"pl": "Wszystkie testy molecule zakończone pomyślnie.",
"ru": "All molecule tests passed.",
"zh": "All molecule tests passed."
},
"Allow empty tag (PR mode where SHA is concrete).": {
"bg": "Позволи празен таг (PR режим, където SHA е конкретен).",
"de": "Leeren Tag zulassen (PR-Modus, in dem SHA konkret ist).",
@@ -799,13 +791,13 @@
"ru": "Разрешить пустой тег (режим PR, где SHA конкретен).",
"zh": "允许空标签(SHA 为具体值的 PR 模式)。"
},
"Another molecule runner failed. Stopping this runner early.": {
"bg": "Another molecule runner failed. Stopping this runner early.",
"de": "Another molecule runner failed. Stopping this runner early.",
"en": "Another molecule runner failed. Stopping this runner early.",
"pl": "Inny runner molecule zakończył się niepowodzeniem. Wczesne zatrzymanie tego runnera.",
"ru": "Another molecule runner failed. Stopping this runner early.",
"zh": "Another molecule runner failed. Stopping this runner early."
"Another runner failed. Stopping this runner early.": {
"bg": "Друг runner се провали. Спиране на този runner по-рано.",
"de": "Ein anderer Runner ist fehlgeschlagen. Dieser Runner wird vorzeitig gestoppt.",
"en": "Another runner failed. Stopping this runner early.",
"pl": "Inny runner zakończył się niepowodzeniem. Wczesne zatrzymanie tego runnera.",
"ru": "Другой runner завершился с ошибкой. Останавливаю этот runner досрочно.",
"zh": "另一个 runner 失败。提前停止此 runner。"
},
"Assigned {count} files to runner {runner_index}": {
"bg": "Assigned {count} files to runner {runner_index}",
@@ -1495,14 +1487,6 @@
"ru": "FAILED: {count} undocumented dependency/ies",
"zh": "FAILED: {count} undocumented dependency/ies"
},
"FAILED: {pair} exited with code {code}": {
"bg": "FAILED: {pair} exited with code {code}",
"de": "FAILED: {pair} exited with code {code}",
"en": "FAILED: {pair} exited with code {code}",
"pl": "NIEUDANE: {pair} zakończone kodem {code}",
"ru": "FAILED: {pair} exited with code {code}",
"zh": "FAILED: {pair} exited with code {code}"
},
"Failed images: {names}": {
"bg": "Failed images: {names}",
"de": "Failed images: {names}",
@@ -2263,14 +2247,6 @@
"ru": "PASS: All documentation checks passed!",
"zh": "PASS: All documentation checks passed!"
},
"PASSED: {pair}": {
"bg": "PASSED: {pair}",
"de": "PASSED: {pair}",
"en": "PASSED: {pair}",
"pl": "UDANE: {pair}",
"ru": "PASSED: {pair}",
"zh": "PASSED: {pair}"
},
"PR #{pr} rebased successfully. A new CI run will start automatically.\nIf auto-merge is enabled (ready-to-merge label), the next CI run\nwill attempt to merge this PR.": {
"bg": "PR #{pr} rebased successfully. A new CI run will start automatically.\nIf auto-merge is enabled (ready-to-merge label), the next CI run\nwill attempt to merge this PR.",
"de": "PR #{pr} rebased successfully. A new CI run will start automatically.\nIf auto-merge is enabled (ready-to-merge label), the next CI run\nwill attempt to merge this PR.",
@@ -2743,14 +2719,6 @@
"ru": "Running: {cmd}",
"zh": "Running: {cmd}"
},
"Running: {scenario} on {platform}": {
"bg": "Running: {scenario} on {platform}",
"de": "Running: {scenario} on {platform}",
"en": "Running: {scenario} on {platform}",
"pl": "Uruchamianie: {scenario} na {platform}",
"ru": "Running: {scenario} on {platform}",
"zh": "Running: {scenario} on {platform}"
},
"SSH key set up successfully": {
"bg": "SSH ключът е настроен успешно",
"de": "SSH-Schlüssel erfolgreich eingerichtet",
@@ -3830,13 +3798,5 @@
"pl": "[check-test-speed] CI environment detected — scaling limits by {factor}x (total: {orig}s → {eff}s, per-test: {orig_s}s → {eff_s}s)",
"ru": "[check-test-speed] CI environment detected — scaling limits by {factor}x (total: {orig}s → {eff}s, per-test: {orig_s}s → {eff_s}s)",
"zh": "[check-test-speed] CI environment detected — scaling limits by {factor}x (total: {orig}s → {eff}s, per-test: {orig_s}s → {eff_s}s)"
},
"Cleaning up: running molecule destroy for {scenario}": {
"en": "Cleaning up: running molecule destroy for {scenario}",
"bg": "Изчистване: изпълнение на molecule destroy за {scenario}",
"de": "Aufräumen: molecule destroy wird ausgeführt für {scenario}",
"pl": "Czyszczenie: uruchamianie molecule destroy dla {scenario}",
"ru": "Очистка: запуск molecule destroy для {scenario}",
"zh": "清理:正在为 {scenario} 运行 molecule destroy"
}
}