From f98534ebe28c6c74b576d14cc1edc4a3bf8fb85d Mon Sep 17 00:00:00 2001 From: emil Date: Tue, 7 Jul 2026 11:57:04 +0000 Subject: [PATCH] DEVX-119: feat: add GiteaClient repo variable methods and parallelize pytest-cov --- .gitea/workflows/ci.yml | 3 +- docker/ci-quality/Dockerfile | 2 +- docs/tech/architecture.md | 4 +- src/devx/api_clients.py | 29 + src/devx/make/devx.mak | 10 +- src/devx/translations.json | 1432 ++++++++++++++++++-------------- tests/unit/test_api_clients.py | 62 ++ 7 files changed, 919 insertions(+), 623 deletions(-) diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index c3b5c1e..1a87be3 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -55,8 +55,7 @@ jobs: PYTHONPATH: src run: | . .venv/bin/activate 2>/dev/null || true - export PATH="$HOME/.local/bin:$PATH" - vale --minAlertLevel=error docs/ AGENTS.md README.md + make devx-vale - name: Translation completeness check env: PYTHONPATH: src diff --git a/docker/ci-quality/Dockerfile b/docker/ci-quality/Dockerfile index 60dfe0c..b164755 100644 --- a/docker/ci-quality/Dockerfile +++ b/docker/ci-quality/Dockerfile @@ -13,7 +13,7 @@ RUN pip install --no-cache-dir /tmp/devx[lint] \ && rm -rf /tmp/devx # Install CI/CD binary tools -RUN python3 -m devx.tools.install_tools --tool actionlint \ +RUN python3 -m devx.tools.install_tools --tool actionlint --tool vale \ && python3 -m devx.tools.install_checkmake # Install hadolint (Dockerfile linter) diff --git a/docs/tech/architecture.md b/docs/tech/architecture.md index 7663692..2ab8a60 100644 --- a/docs/tech/architecture.md +++ b/docs/tech/architecture.md @@ -122,7 +122,9 @@ exponential backoff (2s, 4s, 8s). - Labels (list, create, add to issues) - Issues (create, list) - Pull requests (get commits, merge, create review) -- Releases (list) +- Releases (list, create idempotent) +- Actions (list runs, list jobs, get job logs) +- Actions variables (get, set idempotent) - Wiki pages (list, fetch, create, update, delete) **`VikunjaClient`** — Vikunja REST API wrapper: diff --git a/src/devx/api_clients.py b/src/devx/api_clients.py index d921f93..3d2e690 100644 --- a/src/devx/api_clients.py +++ b/src/devx/api_clients.py @@ -372,6 +372,35 @@ class GiteaClient: r = self._request("GET", f"/actions/jobs/{job_id}/logs") return r.text + # -- actions variables (repo-level) -- + + def get_repo_variable(self, name: str) -> str | None: + """Read a Gitea Actions repository variable. + + Returns the variable value, or ``None`` if the variable is not set. + Raises :class:`APIError` on other HTTP errors. + """ + try: + r = self._request("GET", f"/actions/variables/{name}") + return r.json().get("value") + except APIError as e: + if e.status == 404: + return None + raise + + def set_repo_variable(self, name: str, value: str) -> None: + """Create or update a Gitea Actions repository variable (idempotent). + + Tries PATCH first; if the variable doesn't exist (404), creates it + via POST. + """ + try: + self._request("PATCH", f"/actions/variables/{name}", json={"value": value}) + except APIError as e: + if e.status != 404: + raise + self._request("POST", "/actions/variables", json={"name": name, "value": value}) + class VikunjaClient: """Low-level Vikunja REST API client with connection pooling.""" diff --git a/src/devx/make/devx.mak b/src/devx/make/devx.mak index 2a96485..28419ea 100644 --- a/src/devx/make/devx.mak +++ b/src/devx/make/devx.mak @@ -304,7 +304,7 @@ devx-test-unit: @$(DEVX_BIN)/pytest $(DEVX_TEST_PATHS) -q --no-cov devx-pytest-cov: - @$(DEVX_BIN)/pytest $(DEVX_TEST_PATHS) -v --cov=$(DEVX_COV_PKG) --cov-report=term-missing --cov-fail-under=100 + @$(DEVX_BIN)/pytest $(DEVX_TEST_PATHS) -n auto --cov=$(DEVX_COV_PKG) --cov-report=term-missing --cov-fail-under=100 # ── Quality checks ──────────────────────────────────────────────────────────── @@ -328,10 +328,14 @@ devx-check-docs: devx-check-doc-versions: @$(DEVX_PYTHON) -m devx.tools.check_doc_versions --root . -# Run Vale prose linter on docs and README +# Run Vale prose linter on docs and README (skips if vale not installed) devx-vale: @export PATH="$$HOME/.local/bin:$$PATH" && \ - vale --minAlertLevel=error docs/ AGENTS.md README.md + if ! command -v vale >/dev/null 2>&1; then \ + echo "[devx-vale] vale not installed — skipping (install with 'make install-tools')"; \ + else \ + vale --minAlertLevel=error docs/ AGENTS.md README.md; \ + fi # Verify test suite timing devx-check-test-speed: diff --git a/src/devx/translations.json b/src/devx/translations.json index 39fab56..b4cacc1 100644 --- a/src/devx/translations.json +++ b/src/devx/translations.json @@ -47,13 +47,13 @@ "ru": "\nDoc coverage: {covered}/{total} ({pct}%)", "zh": "\nDoc coverage: {covered}/{total} ({pct}%)" }, - "\nDone! Created: {created}, Updated: {updated}, Skipped: {skipped}": { - "bg": "\nDone! Created: {created}, Updated: {updated}, Skipped: {skipped}", - "de": "\nDone! Created: {created}, Updated: {updated}, Skipped: {skipped}", - "en": "\nDone! Created: {created}, Updated: {updated}, Skipped: {skipped}", - "pl": "\nGotowe! Utworzono: {created}, Zaktualizowano: {updated}, Pominięto: {skipped}", - "ru": "\nDone! Created: {created}, Updated: {updated}, Skipped: {skipped}", - "zh": "\nDone! Created: {created}, Updated: {updated}, Skipped: {skipped}" + "\nDone! Synced: {synced}, Pruned: {pruned}": { + "bg": "", + "de": "", + "en": "\nDone! Synced: {synced}, Pruned: {pruned}", + "pl": "", + "ru": "", + "zh": "" }, "\nDone. Deleted {deleted}, kept {kept}, failed {failed}.": { "bg": "\nDone. Deleted {deleted}, kept {kept}, failed {failed}.", @@ -71,6 +71,14 @@ "ru": "\nERROR: Documentation coverage is not 100%. Use --fail-on-missing to enforce.", "zh": "\nERROR: Documentation coverage is not 100%. Use --fail-on-missing to enforce." }, + "\nFAIL: {n} stale version reference(s) found:": { + "bg": "", + "de": "", + "en": "\nFAIL: {n} stale version reference(s) found:", + "pl": "", + "ru": "", + "zh": "" + }, "\nFix the misaligned tags before creating new releases. Run 'python3 -m devx.ci.release --verify' for a full report.": { "bg": "\nFix the misaligned tags before creating new releases. Run 'python3 -m devx.ci.release --verify' for a full report.", "de": "\nFix the misaligned tags before creating new releases. Run 'python3 -m devx.ci.release --verify' for a full report.", @@ -79,6 +87,14 @@ "ru": "\nFix the misaligned tags before creating new releases. Run 'python3 -m devx.ci.release --verify' for a full report.", "zh": "\nFix the misaligned tags before creating new releases. Run 'python3 -m devx.ci.release --verify' for a full report." }, + "\nFixed {n} stale version reference(s).": { + "bg": "", + "de": "", + "en": "\nFixed {n} stale version reference(s).", + "pl": "", + "ru": "", + "zh": "" + }, "\nGenerated {count} badges:": { "bg": "\nGenerated {count} badges:", "de": "\nGenerated {count} badges:", @@ -87,22 +103,6 @@ "ru": "\nGenerated {count} badges:", "zh": "\nGenerated {count} badges:" }, - "\nIntegrity check FAILED ({count} issues):": { - "bg": "\nIntegrity check FAILED ({count} issues):", - "de": "\nIntegrity check FAILED ({count} issues):", - "en": "\nIntegrity check FAILED ({count} issues):", - "pl": "\nKontrola integralności NIEUDANA ({count} problemów):", - "ru": "\nIntegrity check FAILED ({count} issues):", - "zh": "\nIntegrity check FAILED ({count} issues):" - }, - "\nIntegrity check passed — all {count} pages verified.": { - "bg": "\nIntegrity check passed — all {count} pages verified.", - "de": "\nIntegrity check passed — all {count} pages verified.", - "en": "\nIntegrity check passed — all {count} pages verified.", - "pl": "\nKontrola integralności zakończona pomyślnie — wszystkie {count} stron zweryfikowane.", - "ru": "\nIntegrity check passed — all {count} pages verified.", - "zh": "\nIntegrity check passed — all {count} pages verified." - }, "\nKeeping {kept}, would delete {count}": { "bg": "\nKeeping {kept}, would delete {count}", "de": "\nKeeping {kept}, would delete {count}", @@ -127,6 +127,22 @@ "ru": "\nMissing documentation:", "zh": "\nMissing documentation:" }, + "\nNo stale version references found.": { + "bg": "", + "de": "", + "en": "\nNo stale version references found.", + "pl": "", + "ru": "", + "zh": "" + }, + "\nPASS: All version references are current.": { + "bg": "", + "de": "", + "en": "\nPASS: All version references are current.", + "pl": "", + "ru": "", + "zh": "" + }, "\nResult: {status}": { "bg": "\nResult: {status}", "de": "\nResult: {status}", @@ -151,13 +167,13 @@ "ru": "\nReview #{review_id} posted on PR #{pr_number} with event '{event}'.", "zh": "\nReview #{review_id} posted on PR #{pr_number} with event '{event}'." }, - "\nRunning full wiki integrity check...": { - "bg": "\nRunning full wiki integrity check...", - "de": "\nRunning full wiki integrity check...", - "en": "\nRunning full wiki integrity check...", - "pl": "\nUruchamianie pełnej kontroli integralności wiki...", - "ru": "\nRunning full wiki integrity check...", - "zh": "\nRunning full wiki integrity check..." + "\nRun with --fix to auto-update version references.": { + "bg": "", + "de": "", + "en": "\nRun with --fix to auto-update version references.", + "pl": "", + "ru": "", + "zh": "" }, "\nTag → Commit alignment:": { "bg": "\nTag → Commit alignment:", @@ -183,29 +199,21 @@ "ru": "\nUser-facing changes ({count}):", "zh": "\nUser-facing changes ({count}):" }, - "\nVerification FAILED: {failures} page(s) have empty or mismatched content!": { - "bg": "\nVerification FAILED: {failures} page(s) have empty or mismatched content!", - "de": "\nVerification FAILED: {failures} page(s) have empty or mismatched content!", - "en": "\nVerification FAILED: {failures} page(s) have empty or mismatched content!", - "pl": "\nWeryfikacja NIEUDANA: {failures} strona(y) ma pustą lub niezgodną treść!", - "ru": "\nVerification FAILED: {failures} page(s) have empty or mismatched content!", - "zh": "\nVerification FAILED: {failures} page(s) have empty or mismatched content!" + "\nVerification passed — all wiki pages exist.": { + "bg": "", + "de": "", + "en": "\nVerification passed — all wiki pages exist.", + "pl": "", + "ru": "", + "zh": "" }, - "\nVerification passed — all wiki pages have correct content.": { - "bg": "\nVerification passed — all wiki pages have correct content.", - "de": "\nVerification passed — all wiki pages have correct content.", - "en": "\nVerification passed — all wiki pages have correct content.", - "pl": "\nWeryfikacja zakończona pomyślnie — wszystkie strony wiki mają poprawną treść.", - "ru": "\nVerification passed — all wiki pages have correct content.", - "zh": "\nVerification passed — all wiki pages have correct content." - }, - "\nVerifying wiki pages have content...": { - "bg": "\nVerifying wiki pages have content...", - "de": "\nVerifying wiki pages have content...", - "en": "\nVerifying wiki pages have content...", - "pl": "\nWeryfikowanie, czy strony wiki mają treść...", - "ru": "\nVerifying wiki pages have content...", - "zh": "\nVerifying wiki pages have content..." + "\nVerifying wiki pages...": { + "bg": "", + "de": "", + "en": "\nVerifying wiki pages...", + "pl": "", + "ru": "", + "zh": "" }, "\nWorkflow-only changes ({count}):": { "bg": "\nWorkflow-only changes ({count}):", @@ -351,6 +359,30 @@ "ru": " - Требуемые проверки статуса: {checks}", "zh": " - 必需状态检查: {checks}" }, + " - {count} standard labels verified": { + "bg": " - {count} standard labels verified", + "de": " - {count} standard labels verified", + "en": " - {count} standard labels verified", + "pl": " - {count} standard labels verified", + "ru": " - {count} standard labels verified", + "zh": " - {count} standard labels verified" + }, + " -> {dir}": { + "en": " -> {dir}", + "bg": " -> {dir}", + "de": " -> {dir}", + "pl": " -> {dir}", + "ru": " -> {dir}", + "zh": " -> {dir}" + }, + " ... and {n} more": { + "bg": "", + "de": "", + "en": " ... and {n} more", + "pl": "", + "ru": "", + "zh": "" + }, " Auto-fixed trailing whitespace in {n} files": { "bg": " Auto-fixed trailing whitespace in {n} files", "de": " Auto-fixed trailing whitespace in {n} files", @@ -391,14 +423,6 @@ "ru": " Collecting version...", "zh": " Collecting version..." }, - " Created: {title}": { - "bg": " Created: {title}", - "de": " Created: {title}", - "en": " Created: {title}", - "pl": " Utworzono: {title}", - "ru": " Created: {title}", - "zh": " Created: {title}" - }, " Deleted: {version}": { "bg": " Deleted: {version}", "de": " Deleted: {version}", @@ -407,13 +431,13 @@ "ru": " Deleted: {version}", "zh": " Deleted: {version}" }, - " FAIL: {title} — content mismatch or empty!": { - "bg": " FAIL: {title} — content mismatch or empty!", - "de": " FAIL: {title} — content mismatch or empty!", - "en": " FAIL: {title} — content mismatch or empty!", - "pl": " BŁĄD: {title} — treść niezgodna lub pusta!", - "ru": " FAIL: {title} — content mismatch or empty!", - "zh": " FAIL: {title} — content mismatch or empty!" + " FAIL: {title} — page not found in wiki!": { + "bg": "", + "de": "", + "en": " FAIL: {title} — page not found in wiki!", + "pl": "", + "ru": "", + "zh": "" }, " FAILED to delete: {version}": { "bg": " FAILED to delete: {version}", @@ -423,6 +447,14 @@ "ru": " FAILED to delete: {version}", "zh": " FAILED to delete: {version}" }, + " Fixed {fixes} version ref(s) in {file}": { + "bg": "", + "de": "", + "en": " Fixed {fixes} version ref(s) in {file}", + "pl": "", + "ru": "", + "zh": "" + }, " Generated: {path}": { "bg": " Generated: {path}", "de": " Generated: {path}", @@ -479,13 +511,13 @@ "ru": " OK: {script}", "zh": " OK: {script}" }, - " OK: {title} ({chars} chars)": { - "bg": " OK: {title} ({chars} chars)", - "de": " OK: {title} ({chars} chars)", - "en": " OK: {title} ({chars} chars)", - "pl": " OK: {title} ({chars} znaków)", - "ru": " OK: {title} ({chars} chars)", - "zh": " OK: {title} ({chars} chars)" + " OK: {title}": { + "bg": "", + "de": "", + "en": " OK: {title}", + "pl": "", + "ru": "", + "zh": "" }, " Package: {pkg}": { "bg": " Package: {pkg}", @@ -495,6 +527,14 @@ "ru": " Package: {pkg}", "zh": " Package: {pkg}" }, + " Pruned: {file} (not in mapping)": { + "bg": "", + "de": "", + "en": " Pruned: {file} (not in mapping)", + "pl": "", + "ru": "", + "zh": "" + }, " Quality checks: {checks}": { "bg": " Quality checks: {checks}", "de": " Quality checks: {checks}", @@ -511,6 +551,22 @@ "ru": " Repo root: {root}", "zh": " Repo root: {root}" }, + " Run 'make install-checkmake' to install the Makefile linter.": { + "en": " Run 'make install-checkmake' to install the Makefile linter.", + "bg": " Изпълнете 'make install-checkmake' за инсталиране на Makefile линтера.", + "de": " Führen Sie 'make install-checkmake' aus, um den Makefile-Linter zu installieren.", + "pl": " Uruchom 'make install-checkmake', aby zainstalować linter Makefile.", + "ru": " Выполните 'make install-checkmake' для установки линтера Makefile.", + "zh": " 运行 'make install-checkmake' 来安装 Makefile 检查器。" + }, + " Synced: {title} → {file}": { + "bg": "", + "de": "", + "en": " Synced: {title} → {file}", + "pl": "", + "ru": "", + "zh": "" + }, " Test paths: {testpaths}": { "bg": " Test paths: {testpaths}", "de": " Test paths: {testpaths}", @@ -519,13 +575,21 @@ "ru": " Test paths: {testpaths}", "zh": " Test paths: {testpaths}" }, - " Updated: {title}": { - "bg": " Updated: {title}", - "de": " Updated: {title}", - "en": " Updated: {title}", - "pl": " Zaktualizowano: {title}", - "ru": " Updated: {title}", - "zh": " Updated: {title}" + " WARN: Mapped file {file} is empty, skipping": { + "bg": "", + "de": "", + "en": " WARN: Mapped file {file} is empty, skipping", + "pl": "", + "ru": "", + "zh": "" + }, + " WARN: Mapped file {file} not found, skipping": { + "bg": "", + "de": "", + "en": " WARN: Mapped file {file} not found, skipping", + "pl": "", + "ru": "", + "zh": "" }, " WARNING: Could not extract coverage from pytest output (rc={rc})": { "bg": " WARNING: Could not extract coverage from pytest output (rc={rc})", @@ -615,6 +679,22 @@ "ru": " {name}: {label}={message} ({color})", "zh": " {name}: {label}={message} ({color})" }, + " {n} long lines found (warnings only)": { + "bg": "", + "de": "", + "en": " {n} long lines found (warnings only)", + "pl": "", + "ru": "", + "zh": "" + }, + " {n} orphan docs found (warnings only)": { + "bg": "", + "de": "", + "en": " {n} orphan docs found (warnings only)", + "pl": "", + "ru": "", + "zh": "" + }, " {n} stale docs found (warnings only)": { "bg": " {n} stale docs found (warnings only)", "de": " {n} stale docs found (warnings only)", @@ -623,6 +703,14 @@ "ru": " {n} stale docs found (warnings only)", "zh": " {n} stale docs found (warnings only)" }, + " {tool}: found at {path}": { + "en": " {tool}: found at {path}", + "bg": " {tool}: намерен на {path}", + "de": " {tool}: gefunden unter {path}", + "pl": " {tool}: znaleziono w {path}", + "ru": " {tool}: найден в {path}", + "zh": " {tool}: 在 {path} 找到" + }, " {version} (created: {created})": { "bg": " {version} (created: {created})", "de": " {version} (created: {created})", @@ -727,6 +815,22 @@ "ru": "Assigned {count} items to runner {runner_index}: {encoded}", "zh": "Assigned {count} items to runner {runner_index}: {encoded}" }, + "Auto-rebase failed with HTTP {status}: {message}\nRebase manually:\n git fetch origin master && git rebase origin/master && git push --force-with-lease\nThen re-add the ready-to-merge label.": { + "bg": "Auto-rebase failed with HTTP {status}: {message}\nRebase manually:\n git fetch origin master && git rebase origin/master && git push --force-with-lease\nThen re-add the ready-to-merge label.", + "de": "Auto-rebase failed with HTTP {status}: {message}\nRebase manually:\n git fetch origin master && git rebase origin/master && git push --force-with-lease\nThen re-add the ready-to-merge label.", + "en": "Auto-rebase failed with HTTP {status}: {message}\nRebase manually:\n git fetch origin master && git rebase origin/master && git push --force-with-lease\nThen re-add the ready-to-merge label.", + "pl": "Auto-rebase failed with HTTP {status}: {message}\nRebase manually:\n git fetch origin master && git rebase origin/master && git push --force-with-lease\nThen re-add the ready-to-merge label.", + "ru": "Auto-rebase failed with HTTP {status}: {message}\nRebase manually:\n git fetch origin master && git rebase origin/master && git push --force-with-lease\nThen re-add the ready-to-merge label.", + "zh": "Auto-rebase failed with HTTP {status}: {message}\nRebase manually:\n git fetch origin master && git rebase origin/master && git push --force-with-lease\nThen re-add the ready-to-merge label." + }, + "Automated CI commit (badge) — skipping post-merge jobs.": { + "bg": "Automated CI commit (badge) — skipping post-merge jobs.", + "de": "Automated CI commit (badge) — skipping post-merge jobs.", + "en": "Automated CI commit (badge) — skipping post-merge jobs.", + "pl": "Automated CI commit (badge) — skipping post-merge jobs.", + "ru": "Automated CI commit (badge) — skipping post-merge jobs.", + "zh": "Automated CI commit (badge) — skipping post-merge jobs." + }, "Badge push attempt {attempt}/{retries} failed — retrying: {error}": { "bg": "Badge push attempt {attempt}/{retries} failed — retrying: {error}", "de": "Badge push attempt {attempt}/{retries} failed — retrying: {error}", @@ -775,6 +879,22 @@ "ru": "Ветка '{branch}' не содержит ID задачи.\n Ожидаемый формат: {prefix}-N-краткое-описание\n Пример: {prefix}-42-add-feature\n Исправление: переименуйте ветку или создайте задачу Vikunja:\n python -m devx.tools.create_task --title \"Заголовок задачи\"", "zh": "分支 '{branch}' 不包含任务 ID。\n 预期格式: {prefix}-N-简短描述\n 示例: {prefix}-42-add-feature\n 修复: 重命名分支或先创建 Vikunja 任务:\n python -m devx.tools.create_task --title \"任务标题\"" }, + "Branch is already up-to-date with origin/master.": { + "bg": "Branch is already up-to-date with origin/master.", + "de": "Branch is already up-to-date with origin/master.", + "en": "Branch is already up-to-date with origin/master.", + "pl": "Branch is already up-to-date with origin/master.", + "ru": "Branch is already up-to-date with origin/master.", + "zh": "Branch is already up-to-date with origin/master." + }, + "Branch is behind master. Auto-rebasing via Gitea API...\nA new CI run will start automatically after the rebase.\nThe next auto-merge attempt will merge this PR.": { + "bg": "Branch is behind master. Auto-rebasing via Gitea API...\nA new CI run will start automatically after the rebase.\nThe next auto-merge attempt will merge this PR.", + "de": "Branch is behind master. Auto-rebasing via Gitea API...\nA new CI run will start automatically after the rebase.\nThe next auto-merge attempt will merge this PR.", + "en": "Branch is behind master. Auto-rebasing via Gitea API...\nA new CI run will start automatically after the rebase.\nThe next auto-merge attempt will merge this PR.", + "pl": "Branch is behind master. Auto-rebasing via Gitea API...\nA new CI run will start automatically after the rebase.\nThe next auto-merge attempt will merge this PR.", + "ru": "Branch is behind master. Auto-rebasing via Gitea API...\nA new CI run will start automatically after the rebase.\nThe next auto-merge attempt will merge this PR.", + "zh": "Branch is behind master. Auto-rebasing via Gitea API...\nA new CI run will start automatically after the rebase.\nThe next auto-merge attempt will merge this PR." + }, "Branch is behind origin/master. Rebase first: git fetch origin master && git rebase origin/master": { "bg": "Branch is behind origin/master. Rebase first: git fetch origin master && git rebase origin/master", "de": "Branch is behind origin/master. Rebase first: git fetch origin master && git rebase origin/master", @@ -783,6 +903,14 @@ "ru": "Branch is behind origin/master. Rebase first: git fetch origin master && git rebase origin/master", "zh": "Branch is behind origin/master. Rebase first: git fetch origin master && git rebase origin/master" }, + "Branch is {count} commit(s) behind master. Rebasing...": { + "bg": "Branch is {count} commit(s) behind master. Rebasing...", + "de": "Branch is {count} commit(s) behind master. Rebasing...", + "en": "Branch is {count} commit(s) behind master. Rebasing...", + "pl": "Branch is {count} commit(s) behind master. Rebasing...", + "ru": "Branch is {count} commit(s) behind master. Rebasing...", + "zh": "Branch is {count} commit(s) behind master. Rebasing..." + }, "Branch name (e.g., DEVX-256-fix-foo)": { "bg": "Branch name (e.g., DEVX-256-fix-foo)", "de": "Branch name (e.g., DEVX-256-fix-foo)", @@ -847,6 +975,14 @@ "ru": "CI_GITEA_TOKEN is not set.", "zh": "CI_GITEA_TOKEN is not set." }, + "CI_GITEA_TOKEN is not set. Add it to .env or export it.": { + "bg": "CI_GITEA_TOKEN is not set. Add it to .env or export it.", + "de": "CI_GITEA_TOKEN is not set. Add it to .env or export it.", + "en": "CI_GITEA_TOKEN is not set. Add it to .env or export it.", + "pl": "CI_GITEA_TOKEN is not set. Add it to .env or export it.", + "ru": "CI_GITEA_TOKEN is not set. Add it to .env or export it.", + "zh": "CI_GITEA_TOKEN is not set. Add it to .env or export it." + }, "CI_GITEA_TOKEN is not set. Required to create a PR.": { "bg": "CI_GITEA_TOKEN не е зададен. Необходим за създаване на PR.", "de": "CI_GITEA_TOKEN nicht gesetzt. Erforderlich zum Erstellen eines PR.", @@ -863,6 +999,22 @@ "ru": "CI_GITEA_TOKEN not set — skipping login configuration.", "zh": "CI_GITEA_TOKEN not set — skipping login configuration." }, + "Cannot read __version__ from src/{pkg}/__init__.py — skipping.": { + "bg": "", + "de": "", + "en": "Cannot read __version__ from src/{pkg}/__init__.py — skipping.", + "pl": "", + "ru": "", + "zh": "" + }, + "Cannot rebase: not on a branch (detached HEAD).": { + "bg": "Cannot rebase: not on a branch (detached HEAD).", + "de": "Cannot rebase: not on a branch (detached HEAD).", + "en": "Cannot rebase: not on a branch (detached HEAD).", + "pl": "Cannot rebase: not on a branch (detached HEAD).", + "ru": "Cannot rebase: not on a branch (detached HEAD).", + "zh": "Cannot rebase: not on a branch (detached HEAD)." + }, "Checking CLI command documentation...": { "bg": "Checking CLI command documentation...", "de": "Checking CLI command documentation...", @@ -871,6 +1023,14 @@ "ru": "Checking CLI command documentation...", "zh": "Checking CLI command documentation..." }, + "Checking code block languages...": { + "bg": "", + "de": "", + "en": "Checking code block languages...", + "pl": "", + "ru": "", + "zh": "" + }, "Checking docs structure...": { "bg": "Checking docs structure...", "de": "Checking docs structure...", @@ -895,6 +1055,14 @@ "ru": "Checking for TODO/FIXME markers...", "zh": "Checking for TODO/FIXME markers..." }, + "Checking for orphan docs...": { + "bg": "", + "de": "", + "en": "Checking for orphan docs...", + "pl": "", + "ru": "", + "zh": "" + }, "Checking for stale docs...": { "bg": "Checking for stale docs...", "de": "Checking for stale docs...", @@ -919,6 +1087,22 @@ "ru": "Checking internal links...", "zh": "Checking internal links..." }, + "Checking line length...": { + "bg": "", + "de": "", + "en": "Checking line length...", + "pl": "", + "ru": "", + "zh": "" + }, + "Checking max heading depth...": { + "bg": "", + "de": "", + "en": "Checking max heading depth...", + "pl": "", + "ru": "", + "zh": "" + }, "Checking required files...": { "bg": "Checking required files...", "de": "Checking required files...", @@ -927,6 +1111,14 @@ "ru": "Checking required files...", "zh": "Checking required files..." }, + "Checking single H1 per file...": { + "bg": "", + "de": "", + "en": "Checking single H1 per file...", + "pl": "", + "ru": "", + "zh": "" + }, "Checking status for PR #{pr_number}...": { "bg": "Checking status for PR #{pr_number}...", "de": "Checking status for PR #{pr_number}...", @@ -943,6 +1135,30 @@ "ru": "Checking trailing whitespace...", "zh": "Checking trailing whitespace..." }, + "Checking version references for {pkg} (current: v{version})": { + "bg": "", + "de": "", + "en": "Checking version references for {pkg} (current: v{version})", + "pl": "", + "ru": "", + "zh": "" + }, + "Cloned existing wiki.": { + "bg": "", + "de": "", + "en": "Cloned existing wiki.", + "pl": "", + "ru": "", + "zh": "" + }, + "Cloning wiki repo...": { + "bg": "", + "de": "", + "en": "Cloning wiki repo...", + "pl": "", + "ru": "", + "zh": "" + }, "Command failed ({cmd}): {stderr}": { "bg": "Command failed ({cmd}): {stderr}", "de": "Command failed ({cmd}): {stderr}", @@ -967,6 +1183,14 @@ "ru": "Commit: {sha}", "zh": "Commit: {sha}" }, + "Committing and pushing...": { + "bg": "", + "de": "", + "en": "Committing and pushing...", + "pl": "", + "ru": "", + "zh": "" + }, "Comparing {base}..{head} ({count} files changed)": { "bg": "Comparing {base}..{head} ({count} files changed)", "de": "Comparing {base}..{head} ({count} files changed)", @@ -1015,6 +1239,14 @@ "ru": "Configuring tea login '{name}' for {url}...", "zh": "Configuring tea login '{name}' for {url}..." }, + "Could not detect PR number. Use --pr to specify it explicitly,\nor run this command from a branch with an open PR.": { + "bg": "Could not detect PR number. Use --pr to specify it explicitly,\nor run this command from a branch with an open PR.", + "de": "Could not detect PR number. Use --pr to specify it explicitly,\nor run this command from a branch with an open PR.", + "en": "Could not detect PR number. Use --pr to specify it explicitly,\nor run this command from a branch with an open PR.", + "pl": "Could not detect PR number. Use --pr to specify it explicitly,\nor run this command from a branch with an open PR.", + "ru": "Could not detect PR number. Use --pr to specify it explicitly,\nor run this command from a branch with an open PR.", + "zh": "Could not detect PR number. Use --pr to specify it explicitly,\nor run this command from a branch with an open PR." + }, "Could not detect current branch: {error}": { "bg": "Не може да се определи текущия клон: {error}", "de": "Aktueller Branch konnte nicht erkannt werden: {error}", @@ -1031,6 +1263,14 @@ "ru": "Could not determine head SHA for PR #{pr_number}.", "zh": "Could not determine head SHA for PR #{pr_number}." }, + "Could not determine repository. Set DEVX_REPO_OWNER and DEVX_REPO_NAME\nor GITHUB_REPOSITORY environment variables.": { + "bg": "Could not determine repository. Set DEVX_REPO_OWNER and DEVX_REPO_NAME\nor GITHUB_REPOSITORY environment variables.", + "de": "Could not determine repository. Set DEVX_REPO_OWNER and DEVX_REPO_NAME\nor GITHUB_REPOSITORY environment variables.", + "en": "Could not determine repository. Set DEVX_REPO_OWNER and DEVX_REPO_NAME\nor GITHUB_REPOSITORY environment variables.", + "pl": "Could not determine repository. Set DEVX_REPO_OWNER and DEVX_REPO_NAME\nor GITHUB_REPOSITORY environment variables.", + "ru": "Could not determine repository. Set DEVX_REPO_OWNER and DEVX_REPO_NAME\nor GITHUB_REPOSITORY environment variables.", + "zh": "Could not determine repository. Set DEVX_REPO_OWNER and DEVX_REPO_NAME\nor GITHUB_REPOSITORY environment variables." + }, "Could not extract conventional commit message from PR commits.": { "bg": "Could not extract conventional commit message from PR commits.", "de": "Could not extract conventional commit message from PR commits.", @@ -1119,6 +1359,14 @@ "ru": "Dependencies must have documentation comments.", "zh": "Dependencies must have documentation comments." }, + "Directory to scan (default: tests/integration). Can be repeated.": { + "en": "Directory to scan (default: tests/integration). Can be repeated.", + "bg": "Директория за сканиране (по подразбиране: tests/integration). Може да се повтаря.", + "de": "Zu scannendes Verzeichnis (Standard: tests/integration). Kann wiederholt werden.", + "pl": "Katalog do skanowania (domyślnie: tests/integration). Można powtarzać.", + "ru": "Директория для сканирования (по умолчанию: tests/integration). Можно повторять.", + "zh": "要扫描的目录(默认:tests/integration)。可重复。" + }, "Docker daemon already running": { "bg": "Докер демонът вече работи", "de": "Docker-Daemon läuft bereits", @@ -1207,6 +1455,22 @@ "ru": "Каждый элемент должен быть строкой или объектом с 'id', получено {type}", "zh": "每个元素必须是字符串或带有 'id' 的对象,得到 {type}" }, + "Ensuring standard labels...": { + "bg": "Ensuring standard labels...", + "de": "Ensuring standard labels...", + "en": "Ensuring standard labels...", + "pl": "Ensuring standard labels...", + "ru": "Ensuring standard labels...", + "zh": "Ensuring standard labels..." + }, + "FAIL: Could not clone wiki for verification.": { + "bg": "", + "de": "", + "en": "FAIL: Could not clone wiki for verification.", + "pl": "", + "ru": "", + "zh": "" + }, "FAIL: {n} documentation issues found:": { "bg": "FAIL: {n} documentation issues found:", "de": "FAIL: {n} documentation issues found:", @@ -1263,6 +1527,30 @@ "ru": "Failed to list versions for {name}: {error}", "zh": "Failed to list versions for {name}: {error}" }, + "Failed to push release commit after 3 attempts. Manual intervention required.": { + "bg": "Failed to push release commit after 3 attempts. Manual intervention required.", + "de": "Failed to push release commit after 3 attempts. Manual intervention required.", + "en": "Failed to push release commit after 3 attempts. Manual intervention required.", + "pl": "Failed to push release commit after 3 attempts. Manual intervention required.", + "ru": "Failed to push release commit after 3 attempts. Manual intervention required.", + "zh": "Failed to push release commit after 3 attempts. Manual intervention required." + }, + "Failed to start ssh-agent: {error}": { + "en": "Failed to start ssh-agent: {error}", + "bg": "Неуспешно стартиране на ssh-agent: {error}", + "de": "Starten von ssh-agent fehlgeschlagen: {error}", + "pl": "Nie udało się uruchomić ssh-agent: {error}", + "ru": "Не удалось запустить ssh-agent: {error}", + "zh": "启动 ssh-agent 失败: {error}" + }, + "Fetch failed: {error}": { + "bg": "Fetch failed: {error}", + "de": "Fetch failed: {error}", + "en": "Fetch failed: {error}", + "pl": "Fetch failed: {error}", + "ru": "Fetch failed: {error}", + "zh": "Fetch failed: {error}" + }, "Fetching logs for PR #{pr_number}...": { "bg": "Fetching logs for PR #{pr_number}...", "de": "Fetching logs for PR #{pr_number}...", @@ -1271,13 +1559,29 @@ "ru": "Fetching logs for PR #{pr_number}...", "zh": "Fetching logs for PR #{pr_number}..." }, - "Found {count} existing wiki pages.": { - "bg": "Found {count} existing wiki pages.", - "de": "Found {count} existing wiki pages.", - "en": "Found {count} existing wiki pages.", - "pl": "Znaleziono {count} istniejących stron wiki.", - "ru": "Found {count} existing wiki pages.", - "zh": "Found {count} existing wiki pages." + "Fetching origin/master...": { + "bg": "Fetching origin/master...", + "de": "Fetching origin/master...", + "en": "Fetching origin/master...", + "pl": "Fetching origin/master...", + "ru": "Fetching origin/master...", + "zh": "Fetching origin/master..." + }, + "Force-push failed:\n{error}\nThe remote may have unexpected commits. Fetch and try again.": { + "bg": "Force-push failed:\n{error}\nThe remote may have unexpected commits. Fetch and try again.", + "de": "Force-push failed:\n{error}\nThe remote may have unexpected commits. Fetch and try again.", + "en": "Force-push failed:\n{error}\nThe remote may have unexpected commits. Fetch and try again.", + "pl": "Force-push failed:\n{error}\nThe remote may have unexpected commits. Fetch and try again.", + "ru": "Force-push failed:\n{error}\nThe remote may have unexpected commits. Fetch and try again.", + "zh": "Force-push failed:\n{error}\nThe remote may have unexpected commits. Fetch and try again." + }, + "Force-pushing...": { + "bg": "Force-pushing...", + "de": "Force-pushing...", + "en": "Force-pushing...", + "pl": "Force-pushing...", + "ru": "Force-pushing...", + "zh": "Force-pushing..." }, "Found {count} mutable global(s) — use factory functions or pytest fixtures.": { "bg": "Found {count} mutable global(s) — use factory functions or pytest fixtures.", @@ -1295,6 +1599,14 @@ "ru": "Found {count} stale documentation reference(s)", "zh": "Found {count} stale documentation reference(s)" }, + "Found {count} unsafe identity check(s) in integration tests.": { + "en": "Found {count} unsafe identity check(s) in integration tests.", + "bg": "Намерени са {count} небрежни проверки за идентичност в интеграционните тестове.", + "de": "{count} unsichere Identitätsprüfung(en) in Integrationstests gefunden.", + "pl": "Znaleziono {count} niebezpiecznych sprawdzeń tożsamości w testach integracyjnych.", + "ru": "Найдено {count} небезопасных проверок идентичности в интеграционных тестах.", + "zh": "在集成测试中发现 {count} 个不安全的身份检查。" + }, "Found {count} version(s):": { "bg": "Found {count} version(s):", "de": "Found {count} version(s):", @@ -1519,6 +1831,14 @@ "ru": "Linting documentation in {root}...", "zh": "Linting documentation in {root}..." }, + "Login to {registry} failed: {error}": { + "en": "Login to {registry} failed: {error}", + "bg": "Влизането в {registry} не успя: {error}", + "de": "Anmeldung bei {registry} fehlgeschlagen: {error}", + "pl": "Logowanie do {registry} nie powiodło się: {error}", + "ru": "Ошибка входа в {registry}: {error}", + "zh": "登录 {registry} 失败: {error}" + }, "Manifest file not found: {path}": { "bg": "Manifest file not found: {path}", "de": "Manifest file not found: {path}", @@ -1535,22 +1855,6 @@ "ru": "Manifest must be a JSON list", "zh": "Manifest must be a JSON list" }, - "Mapped file {file} is empty. Update the content or remove from mapping.json.": { - "bg": "Mapped file {file} is empty. Update the content or remove from mapping.json.", - "de": "Mapped file {file} is empty. Update the content or remove from mapping.json.", - "en": "Mapped file {file} is empty. Update the content or remove from mapping.json.", - "pl": "Mapowany plik {file} jest pusty. Zaktualizuj treść lub usuń z mapping.json.", - "ru": "Mapped file {file} is empty. Update the content or remove from mapping.json.", - "zh": "Mapped file {file} is empty. Update the content or remove from mapping.json." - }, - "Mapped file {file} not found. Update mapping.json or create the file.": { - "bg": "Mapped file {file} not found. Update mapping.json or create the file.", - "de": "Mapped file {file} not found. Update mapping.json or create the file.", - "en": "Mapped file {file} not found. Update mapping.json or create the file.", - "pl": "Mapowany plik {file} nie znaleziony. Zaktualizuj mapping.json lub utwórz plik.", - "ru": "Mapped file {file} not found. Update mapping.json or create the file.", - "zh": "Mapped file {file} not found. Update mapping.json or create the file." - }, "Merge failed with HTTP {status}: {message}\nPlease check the PR is ready and you have merge rights.": { "bg": "Сливането неуспешно с HTTP {status}: {message}\nПроверете дали PR е готов и имате права за сливане.", "de": "Merge fehlgeschlagen mit HTTP {status}: {message}\nBitte prüfen Sie, ob der PR bereit ist und Sie Merge-Rechte haben.", @@ -1631,6 +1935,14 @@ "ru": "No CI checks found for commit {sha}.", "zh": "No CI checks found for commit {sha}." }, + "No Python package found under src/ — skipping version check.": { + "bg": "", + "de": "", + "en": "No Python package found under src/ — skipping version check.", + "pl": "", + "ru": "", + "zh": "" + }, "No badge SVG files generated": { "bg": "No badge SVG files generated", "de": "No badge SVG files generated", @@ -1647,6 +1959,14 @@ "ru": "No badge URLs found to update — README already up to date", "zh": "No badge URLs found to update — README already up to date" }, + "No badge changes — skipping commit": { + "bg": "", + "de": "", + "en": "No badge changes — skipping commit", + "pl": "", + "ru": "", + "zh": "" + }, "No changes between {base} and {head}.": { "bg": "No changes between {base} and {head}.", "de": "No changes between {base} and {head}.", @@ -1655,6 +1975,14 @@ "ru": "No changes between {base} and {head}.", "zh": "No changes between {base} and {head}." }, + "No changes to sync — wiki is up to date.": { + "bg": "", + "de": "", + "en": "No changes to sync — wiki is up to date.", + "pl": "", + "ru": "", + "zh": "" + }, "No failed jobs.": { "bg": "No failed jobs.", "de": "No failed jobs.", @@ -1687,6 +2015,14 @@ "ru": "No open PR found for branch '{branch}'.", "zh": "No open PR found for branch '{branch}'." }, + "No push needed (no changes or push failed).": { + "bg": "", + "de": "", + "en": "No push needed (no changes or push failed).", + "pl": "", + "ru": "", + "zh": "" + }, "No staged changes — version and changelog already up to date.": { "bg": "No staged changes — version and changelog already up to date.", "de": "No staged changes — version and changelog already up to date.", @@ -1767,6 +2103,14 @@ "ru": "Note: Self-approval not allowed. Posting COMMENT instead.", "zh": "Note: Self-approval not allowed. Posting COMMENT instead." }, + "Nothing to push.": { + "bg": "Nothing to push.", + "de": "Nothing to push.", + "en": "Nothing to push.", + "pl": "Nothing to push.", + "ru": "Nothing to push.", + "zh": "Nothing to push." + }, "Only check staged files (for pre-commit)": { "bg": "Only check staged files (for pre-commit)", "de": "Only check staged files (for pre-commit)", @@ -1871,6 +2215,14 @@ "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.", + "en": "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.", + "pl": "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.", + "ru": "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.", + "zh": "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." + }, "PR already exists: #{index} — {url}": { "bg": "PR вече съществува: #{index} — {url}", "de": "PR existiert bereits: #{index} — {url}", @@ -2047,6 +2399,14 @@ "ru": "Publishing release {tag}...", "zh": "Publishing release {tag}..." }, + "Push attempt {n}/3 failed: {err}": { + "bg": "Push attempt {n}/3 failed: {err}", + "de": "Push attempt {n}/3 failed: {err}", + "en": "Push attempt {n}/3 failed: {err}", + "pl": "Push attempt {n}/3 failed: {err}", + "ru": "Push attempt {n}/3 failed: {err}", + "zh": "Push attempt {n}/3 failed: {err}" + }, "Push failed for {tag}: {error}": { "bg": "Push failed for {tag}: {error}", "de": "Push failed for {tag}: {error}", @@ -2055,6 +2415,14 @@ "ru": "Push failed for {tag}: {error}", "zh": "Push failed for {tag}: {error}" }, + "Push failed: {error}": { + "bg": "", + "de": "", + "en": "Push failed: {error}", + "pl": "", + "ru": "", + "zh": "" + }, "Pushed README update with badge SHA {sha}": { "bg": "Pushed README update with badge SHA {sha}", "de": "Pushed README update with badge SHA {sha}", @@ -2071,6 +2439,14 @@ "ru": "Pushed release commit to master.", "zh": "Pushed release commit to master." }, + "Pushed {branch} to origin.": { + "bg": "Pushed {branch} to origin.", + "de": "Pushed {branch} to origin.", + "en": "Pushed {branch} to origin.", + "pl": "Pushed {branch} to origin.", + "ru": "Pushed {branch} to origin.", + "zh": "Pushed {branch} to origin." + }, "PyPI publish failed (non-fatal — continuing to Gitea release):\n{error}": { "bg": "Публикуването в PyPI неуспешно (некритично — продължава към Gitea release):\n{error}", "de": "PyPI-Veröffentlichung fehlgeschlagen (nicht fatal — Gitea-Release wird fortgesetzt):\n{error}", @@ -2087,6 +2463,46 @@ "ru": "REPO argument is required (or set GITHUB_REPOSITORY env var).", "zh": "REPO argument is required (or set GITHUB_REPOSITORY env var)." }, + "Rebase attempt {n}/3 failed: {err}": { + "bg": "Rebase attempt {n}/3 failed: {err}", + "de": "Rebase attempt {n}/3 failed: {err}", + "en": "Rebase attempt {n}/3 failed: {err}", + "pl": "Rebase attempt {n}/3 failed: {err}", + "ru": "Rebase attempt {n}/3 failed: {err}", + "zh": "Rebase attempt {n}/3 failed: {err}" + }, + "Rebase failed (conflicts or other error):\n{error}\nResolve conflicts and run: git rebase --continue": { + "bg": "Rebase failed (conflicts or other error):\n{error}\nResolve conflicts and run: git rebase --continue", + "de": "Rebase failed (conflicts or other error):\n{error}\nResolve conflicts and run: git rebase --continue", + "en": "Rebase failed (conflicts or other error):\n{error}\nResolve conflicts and run: git rebase --continue", + "pl": "Rebase failed (conflicts or other error):\n{error}\nResolve conflicts and run: git rebase --continue", + "ru": "Rebase failed (conflicts or other error):\n{error}\nResolve conflicts and run: git rebase --continue", + "zh": "Rebase failed (conflicts or other error):\n{error}\nResolve conflicts and run: git rebase --continue" + }, + "Rebase failed with HTTP {status}: {message}": { + "bg": "Rebase failed with HTTP {status}: {message}", + "de": "Rebase failed with HTTP {status}: {message}", + "en": "Rebase failed with HTTP {status}: {message}", + "pl": "Rebase failed with HTTP {status}: {message}", + "ru": "Rebase failed with HTTP {status}: {message}", + "zh": "Rebase failed with HTTP {status}: {message}" + }, + "Rebase successful.": { + "bg": "Rebase successful.", + "de": "Rebase successful.", + "en": "Rebase successful.", + "pl": "Rebase successful.", + "ru": "Rebase successful.", + "zh": "Rebase successful." + }, + "Rebasing PR #{pr} via Gitea API...": { + "bg": "Rebasing PR #{pr} via Gitea API...", + "de": "Rebasing PR #{pr} via Gitea API...", + "en": "Rebasing PR #{pr} via Gitea API...", + "pl": "Rebasing PR #{pr} via Gitea API...", + "ru": "Rebasing PR #{pr} via Gitea API...", + "zh": "Rebasing PR #{pr} via Gitea API..." + }, "Registry credentials required: set CI_GITEA_TOKEN and CI_GITEA_USERNAME env vars": { "bg": "Registry credentials required: set CI_GITEA_TOKEN and CI_GITEA_USERNAME env vars", "de": "Registry credentials required: set CI_GITEA_TOKEN and CI_GITEA_USERNAME env vars", @@ -2127,14 +2543,6 @@ "ru": "Release commit — skipping all post-merge jobs.", "zh": "Release commit — skipping all post-merge jobs." }, - "Automated CI commit (badge) — skipping post-merge jobs.": { - "bg": "Automated CI commit (badge) — skipping post-merge jobs.", - "de": "Automated CI commit (badge) — skipping post-merge jobs.", - "en": "Automated CI commit (badge) — skipping post-merge jobs.", - "pl": "Automated CI commit (badge) — skipping post-merge jobs.", - "ru": "Automated CI commit (badge) — skipping post-merge jobs.", - "zh": "Automated CI commit (badge) — skipping post-merge jobs." - }, "Release creation failed: {error}": { "bg": "Release creation failed: {error}", "de": "Release creation failed: {error}", @@ -2191,6 +2599,14 @@ "ru": "Владелец репозитория не установлен. Используйте --owner или DEVX_REPO_OWNER env var.", "zh": "仓库所有者未设置。使用 --owner 或 DEVX_REPO_OWNER 环境变量。" }, + "Required tools missing.": { + "en": "Required tools missing.", + "bg": "Липсват задължителни инструменти.", + "de": "Erforderliche Werkzeuge fehlen.", + "pl": "Brak wymaganych narzędzi.", + "ru": "Отсутствуют обязательные инструменты.", + "zh": "缺少必需的工具。" + }, "Review body must be at least 50 characters.": { "bg": "Review body must be at least 50 characters.", "de": "Review body must be at least 50 characters.", @@ -2279,6 +2695,30 @@ "ru": "Running: {scenario} on {platform}", "zh": "Running: {scenario} on {platform}" }, + "SSH key set up successfully": { + "en": "SSH key set up successfully", + "bg": "SSH ключът е настроен успешно", + "de": "SSH-Schlüssel erfolgreich eingerichtet", + "pl": "Klucz SSH skonfigurowany pomyślnie", + "ru": "SSH-ключ успешно настроен", + "zh": "SSH 密钥设置成功" + }, + "SSH key setup skipped (no key provided)": { + "en": "SSH key setup skipped (no key provided)", + "bg": "Настройката на SSH ключ е пропусната (не е предоставен ключ)", + "de": "SSH-Schlüssel-Setup übersprungen (kein Schlüssel bereitgestellt)", + "pl": "Pominięto konfigurację klucza SSH (brak klucza)", + "ru": "Настройка SSH-ключа пропущена (ключ не предоставлен)", + "zh": "SSH 密钥设置已跳过(未提供密钥)" + }, + "SSH_PRIVATE_KEY not set — skipping SSH key setup": { + "en": "SSH_PRIVATE_KEY not set — skipping SSH key setup", + "bg": "SSH_PRIVATE_KEY не е зададен — пропускане на SSH ключ настройката", + "de": "SSH_PRIVATE_KEY nicht gesetzt — SSH-Schlüssel-Setup übersprungen", + "pl": "SSH_PRIVATE_KEY nie ustawione — pomijanie konfiguracji klucza SSH", + "ru": "SSH_PRIVATE_KEY не задан — пропуск настройки SSH-ключа", + "zh": "SSH_PRIVATE_KEY 未设置 — 跳过 SSH 密钥设置" + }, "Skip Vikunja title match check": { "bg": "Skip Vikunja title match check", "de": "Skip Vikunja title match check", @@ -2319,13 +2759,21 @@ "ru": "Synced to latest origin/{branch}", "zh": "Synced to latest origin/{branch}" }, - "Syncing {count} documentation pages to wiki...": { - "bg": "Syncing {count} documentation pages to wiki...", - "de": "Syncing {count} documentation pages to wiki...", - "en": "Syncing {count} documentation pages to wiki...", - "pl": "Synchronizowanie {count} stron dokumentacji do wiki...", - "ru": "Syncing {count} documentation pages to wiki...", - "zh": "Syncing {count} documentation pages to wiki..." + "Syncing files...": { + "bg": "", + "de": "", + "en": "Syncing files...", + "pl": "", + "ru": "", + "zh": "" + }, + "Syncing {count} documentation pages to wiki via Git...": { + "bg": "", + "de": "", + "en": "Syncing {count} documentation pages to wiki via Git...", + "pl": "", + "ru": "", + "zh": "" }, "Tag consistency check failed.": { "bg": "Tag consistency check failed.", @@ -2439,6 +2887,14 @@ "ru": "Updated badge URLs in {filename}", "zh": "Updated badge URLs in {filename}" }, + "Updated documentation version references to v{version}": { + "bg": "", + "de": "", + "en": "Updated documentation version references to v{version}", + "pl": "", + "ru": "", + "zh": "" + }, "Updated version in {init}": { "bg": "Updated version in {init}", "de": "Updated version in {init}", @@ -2455,6 +2911,14 @@ "ru": "Updated {changelog_file}", "zh": "Updated {changelog_file}" }, + "Use string comparison or _is_truthy()/_is_falsy() helpers instead. Add '{marker}' to suppress individual lines.": { + "en": "Use string comparison or _is_truthy()/_is_falsy() helpers instead. Add '{marker}' to suppress individual lines.", + "bg": "Използвайте сравнение на низове или _is_truthy()/_is_falsy() помощници. Добавете '{marker}' за потискане на отделни редове.", + "de": "Verwenden Sie String-Vergleich oder _is_truthy()/_is_falsy() Hilfsfunktionen. Fügen Sie '{marker}' hinzu, um einzelne Zeilen zu unterdrücken.", + "pl": "Użyj porównania ciągów lub pomocników _is_truthy()/_is_falsy(). Dodaj '{marker}', aby pominąć pojedyncze linie.", + "ru": "Используйте строковое сравнение или помощники _is_truthy()/_is_falsy(). Добавьте '{marker}' для подавления отдельных строк.", + "zh": "使用字符串比较或 _is_truthy()/_is_falsy() 辅助函数。添加 '{marker}' 以抑制个别行。" + }, "VIKUNJA_TOKEN is not set. Required to derive PR title.": { "bg": "VIKUNJA_TOKEN не е зададен. Необходим за извличане на PR заглавие.", "de": "VIKUNJA_TOKEN nicht gesetzt. Erforderlich zum Ableiten des PR-Titels.", @@ -2511,6 +2975,38 @@ "ru": "Задача Vikunja {task_id} не найдена в проекте {project_id}.\n Сначала создайте её:\n python -m devx.tools.create_task --title \"Заголовок задачи\"\n Или проверьте, что ID задачи в имени ветки корректен.", "zh": "在项目 {project_id} 中找不到 Vikunja 任务 {task_id}。\n 请先创建:\n python -m devx.tools.create_task --title \"任务标题\"\n 或检查分支名称中的任务 ID 是否正确。" }, + "WARN: .venv has Python {version}, but >={req} is required.": { + "en": "WARN: .venv has Python {version}, but >={req} is required.", + "bg": "ПРЕДУПРЕЖДЕНИЕ: .venv има Python {version}, но се изисква >={req}.", + "de": "WARNUNG: .venv hat Python {version}, aber >={req} ist erforderlich.", + "pl": "OSTRZEŻENIE: .venv ma Python {version}, ale wymagane jest >={req}.", + "ru": "ПРЕДУПРЕЖДЕНИЕ: в .venv установлен Python {version}, но требуется >={req}.", + "zh": "警告: .venv 的 Python 版本为 {version},但要求 >={req}。" + }, + "WARN: .venv not found. Run 'make setup-venv' to create it.": { + "en": "WARN: .venv not found. Run 'make setup-venv' to create it.", + "bg": "ПРЕДУПРЕЖДЕНИЕ: .venv не е намерен. Изпълнете 'make setup-venv' за създаване.", + "de": "WARNUNG: .venv nicht gefunden. Führen Sie 'make setup-venv' aus, um es zu erstellen.", + "pl": "OSTRZEŻENIE: Nie znaleziono .venv. Uruchom 'make setup-venv', aby utworzyć.", + "ru": "ПРЕДУПРЕЖДЕНИЕ: .venv не найден. Выполните 'make setup-venv' для создания.", + "zh": "警告: 未找到 .venv。运行 'make setup-venv' 来创建。" + }, + "WARN: Could not determine Python version in .venv.": { + "en": "WARN: Could not determine Python version in .venv.", + "bg": "ПРЕДУПРЕЖДЕНИЕ: Не може да се определи версията на Python в .venv.", + "de": "WARNUNG: Python-Version in .venv konnte nicht bestimmt werden.", + "pl": "OSTRZEŻENIE: Nie można określić wersji Python w .venv.", + "ru": "ПРЕДУПРЕЖДЕНИЕ: Не удалось определить версию Python в .venv.", + "zh": "警告: 无法确定 .venv 中的 Python 版本。" + }, + "WARN: Could not parse Python version '{version}'.": { + "en": "WARN: Could not parse Python version '{version}'.", + "bg": "ПРЕДУПРЕЖДЕНИЕ: Не може да се анализира версията на Python '{version}'.", + "de": "WARNUNG: Python-Version '{version}' konnte nicht analysiert werden.", + "pl": "OSTRZEŻENIE: Nie można przeanalizować wersji Python '{version}'.", + "ru": "ПРЕДУПРЕЖДЕНИЕ: Не удалось разобрать версию Python '{version}'.", + "zh": "警告: 无法解析 Python 版本 '{version}'。" + }, "WARNING: --skip-tests passed — skipping test verification.": { "bg": "WARNING: --skip-tests passed — skipping test verification.", "de": "WARNING: --skip-tests passed — skipping test verification.", @@ -2527,22 +3023,6 @@ "ru": "ВНИМАНИЕ: Файл .taskid ({file_id}) устарел и не совпадает с именем ветки ({branch_id}). Удалите .taskid из репозитория — имя ветки — единственный источник истины.", "zh": "警告:.taskid 文件 ({file_id}) 已弃用,与分支名称 ({branch_id}) 不一致。请从仓库中删除 .taskid — 分支名称是唯一的真实来源。" }, - "WARNING: Could not fetch wiki page list after retries. The sync itself succeeded ({count} pages updated), but the integrity check could not verify them due to a transient API issue.": { - "bg": "WARNING: Could not fetch wiki page list after retries. The sync itself succeeded ({count} pages updated), but the integrity check could not verify them due to a transient API issue.", - "de": "WARNING: Could not fetch wiki page list after retries. The sync itself succeeded ({count} pages updated), but the integrity check could not verify them due to a transient API issue.", - "en": "WARNING: Could not fetch wiki page list after retries. The sync itself succeeded ({count} pages updated), but the integrity check could not verify them due to a transient API issue.", - "pl": "OSTRZEŻENIE: Nie można pobrać listy stron wiki po ponownych próbach. Sama synchronizacja zakończyła się sukcesem (zaktualizowano {count} stron), ale kontrola integralności nie mogła ich zweryfikować z powodu przejściowego problemu z API.", - "ru": "WARNING: Could not fetch wiki page list after retries. The sync itself succeeded ({count} pages updated), but the integrity check could not verify them due to a transient API issue.", - "zh": "WARNING: Could not fetch wiki page list after retries. The sync itself succeeded ({count} pages updated), but the integrity check could not verify them due to a transient API issue." - }, - "WARNING: Could not re-fetch wiki page list for verification. Skipping content verification due to transient API issue.": { - "bg": "WARNING: Could not re-fetch wiki page list for verification. Skipping content verification due to transient API issue.", - "de": "WARNING: Could not re-fetch wiki page list for verification. Skipping content verification due to transient API issue.", - "en": "WARNING: Could not re-fetch wiki page list for verification. Skipping content verification due to transient API issue.", - "pl": "OSTRZEŻENIE: Nie można ponownie pobrać listy stron wiki do weryfikacji. Pomijanie weryfikacji treści z powodu przejściowego problemu z API.", - "ru": "WARNING: Could not re-fetch wiki page list for verification. Skipping content verification due to transient API issue.", - "zh": "WARNING: Could not re-fetch wiki page list for verification. Skipping content verification due to transient API issue." - }, "WARNING: VIKUNJA_TOKEN not set — skipping task existence check. Set it in .env to enable full validation.": { "bg": "ПРЕДУПРЕЖДЕНИЕ: VIKUNJA_TOKEN не е зададен — пропускане на проверката за съществуване на задача. Задайте го в .env за пълна валидация.", "de": "WARNUNG: VIKUNJA_TOKEN nicht gesetzt — Task-Existenzprüfung übersprungen. In .env setzen für volle Validierung.", @@ -2551,6 +3031,30 @@ "ru": "ПРЕДУПРЕЖДЕНИЕ: VIKUNJA_TOKEN не установлен — пропуск проверки существования задачи. Установите в .env для полной проверки.", "zh": "警告: VIKUNJA_TOKEN 未设置 — 跳过任务存在性检查。在 .env 中设置以启用完整验证。" }, + "WARNING: Version badge shows stale version (expected v{version}) — regenerating": { + "bg": "", + "de": "", + "en": "WARNING: Version badge shows stale version (expected v{version}) — regenerating", + "pl": "", + "ru": "", + "zh": "" + }, + "WARNING: check_doc_versions --fix failed (rc={rc}): {err}": { + "bg": "", + "de": "", + "en": "WARNING: check_doc_versions --fix failed (rc={rc}): {err}", + "pl": "", + "ru": "", + "zh": "" + }, + "Waiting 5s for Gitea to process pushed commits...": { + "bg": "", + "de": "", + "en": "Waiting 5s for Gitea to process pushed commits...", + "pl": "", + "ru": "", + "zh": "" + }, "Waiting for CI checks to complete (timeout: {timeout}s)...": { "bg": "Waiting for CI checks to complete (timeout: {timeout}s)...", "de": "Waiting for CI checks to complete (timeout: {timeout}s)...", @@ -2615,21 +3119,37 @@ "ru": "Warning: repo-level runners query returned HTTP {status}", "zh": "Warning: repo-level runners query returned HTTP {status}" }, - "Wiki integrity check failed — {count} issue(s)": { - "bg": "Wiki integrity check failed — {count} issue(s)", - "de": "Wiki integrity check failed — {count} issue(s)", - "en": "Wiki integrity check failed — {count} issue(s)", - "pl": "Kontrola integralności wiki nie powiodła się — {count} problem(ów)", - "ru": "Wiki integrity check failed — {count} issue(s)", - "zh": "Wiki integrity check failed — {count} issue(s)" + "Wiki repo not found or empty — initializing fresh.": { + "bg": "", + "de": "", + "en": "Wiki repo not found or empty — initializing fresh.", + "pl": "", + "ru": "", + "zh": "" }, - "Wiki verification failed — {failures} page(s) empty or mismatched": { - "bg": "Wiki verification failed — {failures} page(s) empty or mismatched", - "de": "Wiki verification failed — {failures} page(s) empty or mismatched", - "en": "Wiki verification failed — {failures} page(s) empty or mismatched", - "pl": "Weryfikacja wiki nie powiodła się — {failures} strona(y) pusta lub niezgodna", - "ru": "Wiki verification failed — {failures} page(s) empty or mismatched", - "zh": "Wiki verification failed — {failures} page(s) empty or mismatched" + "Wiki synced successfully.": { + "bg": "", + "de": "", + "en": "Wiki synced successfully.", + "pl": "", + "ru": "", + "zh": "" + }, + "Wiki verification failed — could not clone wiki": { + "bg": "", + "de": "", + "en": "Wiki verification failed — could not clone wiki", + "pl": "", + "ru": "", + "zh": "" + }, + "Wiki verification failed — {failures} page(s) missing": { + "bg": "", + "de": "", + "en": "Wiki verification failed — {failures} page(s) missing", + "pl": "", + "ru": "", + "zh": "" }, "Wrote tag {tag} to GITHUB_OUTPUT.": { "bg": "Wrote tag {tag} to GITHUB_OUTPUT.", @@ -2639,6 +3159,14 @@ "ru": "Wrote tag {tag} to GITHUB_OUTPUT.", "zh": "Wrote tag {tag} to GITHUB_OUTPUT." }, + "[check-api-identity-checks] Passed: no unsafe identity checks found": { + "en": "[check-api-identity-checks] Passed: no unsafe identity checks found", + "bg": "[check-api-identity-checks] Мина: не са намерени небрежни проверки за идентичност", + "de": "[check-api-identity-checks] Bestanden: keine unsicheren Identitätsprüfungen gefunden", + "pl": "[check-api-identity-checks] Passed: nie znaleziono niebezpiecznych sprawdzeń tożsamości", + "ru": "[check-api-identity-checks] Пройдено: небезопасных проверок идентичности не найдено", + "zh": "[check-api-identity-checks] 通过:未发现不安全的身份检查" + }, "[check-dep-docs] Passed: all dependencies are documented": { "bg": "[check-dep-docs] Passed: all dependencies are documented", "de": "[check-dep-docs] Passed: all dependencies are documented", @@ -2647,6 +3175,30 @@ "ru": "[check-dep-docs] Passed: all dependencies are documented", "zh": "[check-dep-docs] Passed: all dependencies are documented" }, + "[check-deps] All core tools present.": { + "en": "[check-deps] All core tools present.", + "bg": "[check-deps] Всички основни инструменти са налични.", + "de": "[check-deps] Alle Kernwerkzeuge vorhanden.", + "pl": "[check-deps] Wszystkie podstawowe narzędzia są dostępne.", + "ru": "[check-deps] Все основные инструменты доступны.", + "zh": "[check-deps] 所有核心工具均已就绪。" + }, + "[check-deps] Verifying tools...": { + "en": "[check-deps] Verifying tools...", + "bg": "[check-deps] Проверка на инструментите...", + "de": "[check-deps] Werkzeuge werden überprüft...", + "pl": "[check-deps] Sprawdzanie narzędzi...", + "ru": "[check-deps] Проверка инструментов...", + "zh": "[check-deps] 正在验证工具..." + }, + "[check-deps] Virtualenv .venv ready (Python {version}).": { + "en": "[check-deps] Virtualenv .venv ready (Python {version}).", + "bg": "[check-deps] Виртуална среда .venv готова (Python {version}).", + "de": "[check-deps] Virtuelle Umgebung .venv bereit (Python {version}).", + "pl": "[check-deps] Środowisko wirtualne .venv gotowe (Python {version}).", + "ru": "[check-deps] Виртуальное окружение .venv готово (Python {version}).", + "zh": "[check-deps] 虚拟环境 .venv 已就绪 (Python {version})。" + }, "[check-mutable-globals] Passed: no mutable path globals found": { "bg": "[check-mutable-globals] Passed: no mutable path globals found", "de": "[check-mutable-globals] Passed: no mutable path globals found", @@ -2671,6 +3223,46 @@ "ru": "[check_test_coverage] No changed files to check.", "zh": "[check_test_coverage] No changed files to check." }, + "[docker-login] Logged in to {registry}.": { + "en": "[docker-login] Logged in to {registry}.", + "bg": "[docker-login] Влязъл в {registry}.", + "de": "[docker-login] Angemeldet bei {registry}.", + "pl": "[docker-login] Zalogowano do {registry}.", + "ru": "[docker-login] Выполнен вход в {registry}.", + "zh": "[docker-login] 已登录到 {registry}。" + }, + "[docker-login] Login to {registry} failed (continuing).": { + "en": "[docker-login] Login to {registry} failed (continuing).", + "bg": "[docker-login] Влизането в {registry} не успя (продължава).", + "de": "[docker-login] Anmeldung bei {registry} fehlgeschlagen (wird fortgesetzt).", + "pl": "[docker-login] Logowanie do {registry} nie powiodło się (kontynuowanie).", + "ru": "[docker-login] Ошибка входа в {registry} (продолжаем).", + "zh": "[docker-login] 登录 {registry} 失败(继续)。" + }, + "[docker-login] Skipping {registry} (token {env} not set).": { + "en": "[docker-login] Skipping {registry} (token {env} not set).", + "bg": "[docker-login] Пропускане на {registry} (токен {env} не е зададен).", + "de": "[docker-login] {registry} übersprungen (Token {env} nicht gesetzt).", + "pl": "[docker-login] Pomijanie {registry} (token {env} nie ustawiony).", + "ru": "[docker-login] Пропуск {registry} (токен {env} не задан).", + "zh": "[docker-login] 跳过 {registry}(未设置令牌 {env})。" + }, + "[dry-run] No changes pushed.": { + "bg": "", + "de": "", + "en": "[dry-run] No changes pushed.", + "pl": "", + "ru": "", + "zh": "" + }, + "[dry-run] Would commit and push wiki changes": { + "bg": "", + "de": "", + "en": "[dry-run] Would commit and push wiki changes", + "pl": "", + "ru": "", + "zh": "" + }, "[dry-run] Would commit: release: v{version} [skip ci]": { "bg": "[dry-run] Would commit: release: v{version} [skip ci]", "de": "[dry-run] Would commit: release: v{version} [skip ci]", @@ -2703,13 +3295,13 @@ "ru": "[dry-run] Would push commit to master", "zh": "[dry-run] Would push commit to master" }, - "[dry-run] Would sync page: {title} ({chars} chars)": { - "bg": "[dry-run] Would sync page: {title} ({chars} chars)", - "de": "[dry-run] Would sync page: {title} ({chars} chars)", - "en": "[dry-run] Would sync page: {title} ({chars} chars)", - "pl": "[dry-run] Zsynchronizowano by stronę: {title} ({chars} znaków)", - "ru": "[dry-run] Would sync page: {title} ({chars} chars)", - "zh": "[dry-run] Would sync page: {title} ({chars} chars)" + "[dry-run] Would update doc version references via check_doc_versions --fix": { + "bg": "", + "de": "", + "en": "[dry-run] Would update doc version references via check_doc_versions --fix", + "pl": "", + "ru": "", + "zh": "" }, "[dry-run] Would update {changelog_file}": { "bg": "[dry-run] Would update {changelog_file}", @@ -2727,6 +3319,38 @@ "ru": "[dry-run] Would update {init}", "zh": "[dry-run] Would update {init}" }, + "[tofu-init] Done.": { + "en": "[tofu-init] Done.", + "bg": "[tofu-init] Готово.", + "de": "[tofu-init] Fertig.", + "pl": "[tofu-init] Gotowe.", + "ru": "[tofu-init] Готово.", + "zh": "[tofu-init] 完成。" + }, + "[tofu-init] Initializing {dir}...": { + "en": "[tofu-init] Initializing {dir}...", + "bg": "[tofu-init] Инициализиране на {dir}...", + "de": "[tofu-init] Initialisiere {dir}...", + "pl": "[tofu-init] Inicjalizacja {dir}...", + "ru": "[tofu-init] Инициализация {dir}...", + "zh": "[tofu-init] 正在初始化 {dir}..." + }, + "[tofu-{mode}] All configurations valid.": { + "en": "[tofu-{mode}] All configurations valid.", + "bg": "[tofu-{mode}] Всички конфигурации са валидни.", + "de": "[tofu-{mode}] Alle Konfigurationen gültig.", + "pl": "[tofu-{mode}] Wszystkie konfiguracje są poprawne.", + "ru": "[tofu-{mode}] Все конфигурации валидны.", + "zh": "[tofu-{mode}] 所有配置有效。" + }, + "[tofu-{mode}] Validating OpenTofu configurations...": { + "en": "[tofu-{mode}] Validating OpenTofu configurations...", + "bg": "[tofu-{mode}] Проверка на OpenTofu конфигурациите...", + "de": "[tofu-{mode}] Validiere OpenTofu-Konfigurationen...", + "pl": "[tofu-{mode}] Sprawdzanie konfiguracji OpenTofu...", + "ru": "[tofu-{mode}] Проверка конфигураций OpenTofu...", + "zh": "[tofu-{mode}] 正在验证 OpenTofu 配置..." + }, "[tool.devx] missing required keys: {keys}": { "bg": "[tool.devx] липсват задължителни ключове: {keys}", "de": "[tool.devx] fehlt erforderliche Schlüssel: {keys}", @@ -2879,6 +3503,14 @@ "ru": "tea not installed — skipping login configuration.", "zh": "tea not installed — skipping login configuration." }, + "tofu command failed in {dir}: {error}": { + "en": "tofu command failed in {dir}: {error}", + "bg": "командата tofu не успя в {dir}: {error}", + "de": "tofu-Befehl fehlgeschlagen in {dir}: {error}", + "pl": "polecenie tofu nie powiodło się w {dir}: {error}", + "ru": "команда tofu не удалась в {dir}: {error}", + "zh": "tofu 命令在 {dir} 中失败: {error}" + }, "unknown": { "bg": "неизвестен", "de": "unbekannt", @@ -2887,286 +3519,6 @@ "ru": "неизвестно", "zh": "未知" }, - "{file} already exists. Use --force to overwrite.": { - "bg": "{file} already exists. Use --force to overwrite.", - "de": "{file} already exists. Use --force to overwrite.", - "en": "{file} already exists. Use --force to overwrite.", - "pl": "{file} już istnieje. Użyj --force, aby nadpisać.", - "ru": "{file} already exists. Use --force to overwrite.", - "zh": "{file} already exists. Use --force to overwrite." - }, - "{separator}": { - "bg": "{separator}", - "de": "{separator}", - "en": "{separator}", - "pl": "{separator}", - "ru": "{separator}", - "zh": "{separator}" - }, - "Failed to push release commit after 3 attempts. Manual intervention required.": { - "bg": "Failed to push release commit after 3 attempts. Manual intervention required.", - "de": "Failed to push release commit after 3 attempts. Manual intervention required.", - "en": "Failed to push release commit after 3 attempts. Manual intervention required.", - "pl": "Failed to push release commit after 3 attempts. Manual intervention required.", - "ru": "Failed to push release commit after 3 attempts. Manual intervention required.", - "zh": "Failed to push release commit after 3 attempts. Manual intervention required." - }, - "Push attempt {n}/3 failed: {err}": { - "bg": "Push attempt {n}/3 failed: {err}", - "de": "Push attempt {n}/3 failed: {err}", - "en": "Push attempt {n}/3 failed: {err}", - "pl": "Push attempt {n}/3 failed: {err}", - "ru": "Push attempt {n}/3 failed: {err}", - "zh": "Push attempt {n}/3 failed: {err}" - }, - "Rebase attempt {n}/3 failed: {err}": { - "bg": "Rebase attempt {n}/3 failed: {err}", - "de": "Rebase attempt {n}/3 failed: {err}", - "en": "Rebase attempt {n}/3 failed: {err}", - "pl": "Rebase attempt {n}/3 failed: {err}", - "ru": "Rebase attempt {n}/3 failed: {err}", - "zh": "Rebase attempt {n}/3 failed: {err}" - }, - "Auto-rebase failed with HTTP {status}: {message}\nRebase manually:\n git fetch origin master && git rebase origin/master && git push --force-with-lease\nThen re-add the ready-to-merge label.": { - "bg": "Auto-rebase failed with HTTP {status}: {message}\nRebase manually:\n git fetch origin master && git rebase origin/master && git push --force-with-lease\nThen re-add the ready-to-merge label.", - "de": "Auto-rebase failed with HTTP {status}: {message}\nRebase manually:\n git fetch origin master && git rebase origin/master && git push --force-with-lease\nThen re-add the ready-to-merge label.", - "en": "Auto-rebase failed with HTTP {status}: {message}\nRebase manually:\n git fetch origin master && git rebase origin/master && git push --force-with-lease\nThen re-add the ready-to-merge label.", - "pl": "Auto-rebase failed with HTTP {status}: {message}\nRebase manually:\n git fetch origin master && git rebase origin/master && git push --force-with-lease\nThen re-add the ready-to-merge label.", - "ru": "Auto-rebase failed with HTTP {status}: {message}\nRebase manually:\n git fetch origin master && git rebase origin/master && git push --force-with-lease\nThen re-add the ready-to-merge label.", - "zh": "Auto-rebase failed with HTTP {status}: {message}\nRebase manually:\n git fetch origin master && git rebase origin/master && git push --force-with-lease\nThen re-add the ready-to-merge label." - }, - "Branch is already up-to-date with origin/master.": { - "bg": "Branch is already up-to-date with origin/master.", - "de": "Branch is already up-to-date with origin/master.", - "en": "Branch is already up-to-date with origin/master.", - "pl": "Branch is already up-to-date with origin/master.", - "ru": "Branch is already up-to-date with origin/master.", - "zh": "Branch is already up-to-date with origin/master." - }, - "Branch is behind master. Auto-rebasing via Gitea API...\nA new CI run will start automatically after the rebase.\nThe next auto-merge attempt will merge this PR.": { - "bg": "Branch is behind master. Auto-rebasing via Gitea API...\nA new CI run will start automatically after the rebase.\nThe next auto-merge attempt will merge this PR.", - "de": "Branch is behind master. Auto-rebasing via Gitea API...\nA new CI run will start automatically after the rebase.\nThe next auto-merge attempt will merge this PR.", - "en": "Branch is behind master. Auto-rebasing via Gitea API...\nA new CI run will start automatically after the rebase.\nThe next auto-merge attempt will merge this PR.", - "pl": "Branch is behind master. Auto-rebasing via Gitea API...\nA new CI run will start automatically after the rebase.\nThe next auto-merge attempt will merge this PR.", - "ru": "Branch is behind master. Auto-rebasing via Gitea API...\nA new CI run will start automatically after the rebase.\nThe next auto-merge attempt will merge this PR.", - "zh": "Branch is behind master. Auto-rebasing via Gitea API...\nA new CI run will start automatically after the rebase.\nThe next auto-merge attempt will merge this PR." - }, - "Branch is {count} commit(s) behind master. Rebasing...": { - "bg": "Branch is {count} commit(s) behind master. Rebasing...", - "de": "Branch is {count} commit(s) behind master. Rebasing...", - "en": "Branch is {count} commit(s) behind master. Rebasing...", - "pl": "Branch is {count} commit(s) behind master. Rebasing...", - "ru": "Branch is {count} commit(s) behind master. Rebasing...", - "zh": "Branch is {count} commit(s) behind master. Rebasing..." - }, - "CI_GITEA_TOKEN is not set. Add it to .env or export it.": { - "bg": "CI_GITEA_TOKEN is not set. Add it to .env or export it.", - "de": "CI_GITEA_TOKEN is not set. Add it to .env or export it.", - "en": "CI_GITEA_TOKEN is not set. Add it to .env or export it.", - "pl": "CI_GITEA_TOKEN is not set. Add it to .env or export it.", - "ru": "CI_GITEA_TOKEN is not set. Add it to .env or export it.", - "zh": "CI_GITEA_TOKEN is not set. Add it to .env or export it." - }, - "Cannot rebase: not on a branch (detached HEAD).": { - "bg": "Cannot rebase: not on a branch (detached HEAD).", - "de": "Cannot rebase: not on a branch (detached HEAD).", - "en": "Cannot rebase: not on a branch (detached HEAD).", - "pl": "Cannot rebase: not on a branch (detached HEAD).", - "ru": "Cannot rebase: not on a branch (detached HEAD).", - "zh": "Cannot rebase: not on a branch (detached HEAD)." - }, - "Could not detect PR number. Use --pr to specify it explicitly,\nor run this command from a branch with an open PR.": { - "bg": "Could not detect PR number. Use --pr to specify it explicitly,\nor run this command from a branch with an open PR.", - "de": "Could not detect PR number. Use --pr to specify it explicitly,\nor run this command from a branch with an open PR.", - "en": "Could not detect PR number. Use --pr to specify it explicitly,\nor run this command from a branch with an open PR.", - "pl": "Could not detect PR number. Use --pr to specify it explicitly,\nor run this command from a branch with an open PR.", - "ru": "Could not detect PR number. Use --pr to specify it explicitly,\nor run this command from a branch with an open PR.", - "zh": "Could not detect PR number. Use --pr to specify it explicitly,\nor run this command from a branch with an open PR." - }, - "Could not determine repository. Set DEVX_REPO_OWNER and DEVX_REPO_NAME\nor GITHUB_REPOSITORY environment variables.": { - "bg": "Could not determine repository. Set DEVX_REPO_OWNER and DEVX_REPO_NAME\nor GITHUB_REPOSITORY environment variables.", - "de": "Could not determine repository. Set DEVX_REPO_OWNER and DEVX_REPO_NAME\nor GITHUB_REPOSITORY environment variables.", - "en": "Could not determine repository. Set DEVX_REPO_OWNER and DEVX_REPO_NAME\nor GITHUB_REPOSITORY environment variables.", - "pl": "Could not determine repository. Set DEVX_REPO_OWNER and DEVX_REPO_NAME\nor GITHUB_REPOSITORY environment variables.", - "ru": "Could not determine repository. Set DEVX_REPO_OWNER and DEVX_REPO_NAME\nor GITHUB_REPOSITORY environment variables.", - "zh": "Could not determine repository. Set DEVX_REPO_OWNER and DEVX_REPO_NAME\nor GITHUB_REPOSITORY environment variables." - }, - "Fetch failed: {error}": { - "bg": "Fetch failed: {error}", - "de": "Fetch failed: {error}", - "en": "Fetch failed: {error}", - "pl": "Fetch failed: {error}", - "ru": "Fetch failed: {error}", - "zh": "Fetch failed: {error}" - }, - "Fetching origin/master...": { - "bg": "Fetching origin/master...", - "de": "Fetching origin/master...", - "en": "Fetching origin/master...", - "pl": "Fetching origin/master...", - "ru": "Fetching origin/master...", - "zh": "Fetching origin/master..." - }, - "Force-push failed:\n{error}\nThe remote may have unexpected commits. Fetch and try again.": { - "bg": "Force-push failed:\n{error}\nThe remote may have unexpected commits. Fetch and try again.", - "de": "Force-push failed:\n{error}\nThe remote may have unexpected commits. Fetch and try again.", - "en": "Force-push failed:\n{error}\nThe remote may have unexpected commits. Fetch and try again.", - "pl": "Force-push failed:\n{error}\nThe remote may have unexpected commits. Fetch and try again.", - "ru": "Force-push failed:\n{error}\nThe remote may have unexpected commits. Fetch and try again.", - "zh": "Force-push failed:\n{error}\nThe remote may have unexpected commits. Fetch and try again." - }, - "Force-pushing...": { - "bg": "Force-pushing...", - "de": "Force-pushing...", - "en": "Force-pushing...", - "pl": "Force-pushing...", - "ru": "Force-pushing...", - "zh": "Force-pushing..." - }, - "Nothing to push.": { - "bg": "Nothing to push.", - "de": "Nothing to push.", - "en": "Nothing to push.", - "pl": "Nothing to push.", - "ru": "Nothing to push.", - "zh": "Nothing to push." - }, - "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.", - "en": "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.", - "pl": "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.", - "ru": "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.", - "zh": "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." - }, - "Pushed {branch} to origin.": { - "bg": "Pushed {branch} to origin.", - "de": "Pushed {branch} to origin.", - "en": "Pushed {branch} to origin.", - "pl": "Pushed {branch} to origin.", - "ru": "Pushed {branch} to origin.", - "zh": "Pushed {branch} to origin." - }, - "Rebase failed (conflicts or other error):\n{error}\nResolve conflicts and run: git rebase --continue": { - "bg": "Rebase failed (conflicts or other error):\n{error}\nResolve conflicts and run: git rebase --continue", - "de": "Rebase failed (conflicts or other error):\n{error}\nResolve conflicts and run: git rebase --continue", - "en": "Rebase failed (conflicts or other error):\n{error}\nResolve conflicts and run: git rebase --continue", - "pl": "Rebase failed (conflicts or other error):\n{error}\nResolve conflicts and run: git rebase --continue", - "ru": "Rebase failed (conflicts or other error):\n{error}\nResolve conflicts and run: git rebase --continue", - "zh": "Rebase failed (conflicts or other error):\n{error}\nResolve conflicts and run: git rebase --continue" - }, - "Rebase failed with HTTP {status}: {message}": { - "bg": "Rebase failed with HTTP {status}: {message}", - "de": "Rebase failed with HTTP {status}: {message}", - "en": "Rebase failed with HTTP {status}: {message}", - "pl": "Rebase failed with HTTP {status}: {message}", - "ru": "Rebase failed with HTTP {status}: {message}", - "zh": "Rebase failed with HTTP {status}: {message}" - }, - "Rebase successful.": { - "bg": "Rebase successful.", - "de": "Rebase successful.", - "en": "Rebase successful.", - "pl": "Rebase successful.", - "ru": "Rebase successful.", - "zh": "Rebase successful." - }, - "Rebasing PR #{pr} via Gitea API...": { - "bg": "Rebasing PR #{pr} via Gitea API...", - "de": "Rebasing PR #{pr} via Gitea API...", - "en": "Rebasing PR #{pr} via Gitea API...", - "pl": "Rebasing PR #{pr} via Gitea API...", - "ru": "Rebasing PR #{pr} via Gitea API...", - "zh": "Rebasing PR #{pr} via Gitea API..." - }, - "Ensuring standard labels...": { - "bg": "Ensuring standard labels...", - "de": "Ensuring standard labels...", - "en": "Ensuring standard labels...", - "pl": "Ensuring standard labels...", - "ru": "Ensuring standard labels...", - "zh": "Ensuring standard labels..." - }, - " - {count} standard labels verified": { - "bg": " - {count} standard labels verified", - "de": " - {count} standard labels verified", - "en": " - {count} standard labels verified", - "pl": " - {count} standard labels verified", - "ru": " - {count} standard labels verified", - "zh": " - {count} standard labels verified" - }, - "[check-deps] Virtualenv .venv ready (Python {version}).": { - "en": "[check-deps] Virtualenv .venv ready (Python {version}).", - "bg": "[check-deps] Виртуална среда .venv готова (Python {version}).", - "de": "[check-deps] Virtuelle Umgebung .venv bereit (Python {version}).", - "pl": "[check-deps] Środowisko wirtualne .venv gotowe (Python {version}).", - "ru": "[check-deps] Виртуальное окружение .venv готово (Python {version}).", - "zh": "[check-deps] 虚拟环境 .venv 已就绪 (Python {version})。" - }, - "{level}: {tool} not found.{hint}": { - "en": "{level}: {tool} not found.{hint}", - "bg": "{level}: {tool} не е намерен.{hint}", - "de": "{level}: {tool} nicht gefunden.{hint}", - "pl": "{level}: {tool} nie znaleziono.{hint}", - "ru": "{level}: {tool} не найден.{hint}", - "zh": "{level}: 未找到 {tool}。{hint}" - }, - "WARN: Could not determine Python version in .venv.": { - "en": "WARN: Could not determine Python version in .venv.", - "bg": "ПРЕДУПРЕЖДЕНИЕ: Не може да се определи версията на Python в .venv.", - "de": "WARNUNG: Python-Version in .venv konnte nicht bestimmt werden.", - "pl": "OSTRZEŻENIE: Nie można określić wersji Python w .venv.", - "ru": "ПРЕДУПРЕЖДЕНИЕ: Не удалось определить версию Python в .venv.", - "zh": "警告: 无法确定 .venv 中的 Python 版本。" - }, - "WARN: Could not parse Python version '{version}'.": { - "en": "WARN: Could not parse Python version '{version}'.", - "bg": "ПРЕДУПРЕЖДЕНИЕ: Не може да се анализира версията на Python '{version}'.", - "de": "WARNUNG: Python-Version '{version}' konnte nicht analysiert werden.", - "pl": "OSTRZEŻENIE: Nie można przeanalizować wersji Python '{version}'.", - "ru": "ПРЕДУПРЕЖДЕНИЕ: Не удалось разобрать версию Python '{version}'.", - "zh": "警告: 无法解析 Python 版本 '{version}'。" - }, - "WARN: .venv not found. Run 'make setup-venv' to create it.": { - "en": "WARN: .venv not found. Run 'make setup-venv' to create it.", - "bg": "ПРЕДУПРЕЖДЕНИЕ: .venv не е намерен. Изпълнете 'make setup-venv' за създаване.", - "de": "WARNUNG: .venv nicht gefunden. Führen Sie 'make setup-venv' aus, um es zu erstellen.", - "pl": "OSTRZEŻENIE: Nie znaleziono .venv. Uruchom 'make setup-venv', aby utworzyć.", - "ru": "ПРЕДУПРЕЖДЕНИЕ: .venv не найден. Выполните 'make setup-venv' для создания.", - "zh": "警告: 未找到 .venv。运行 'make setup-venv' 来创建。" - }, - "[docker-login] Logged in to {registry}.": { - "en": "[docker-login] Logged in to {registry}.", - "bg": "[docker-login] Влязъл в {registry}.", - "de": "[docker-login] Angemeldet bei {registry}.", - "pl": "[docker-login] Zalogowano do {registry}.", - "ru": "[docker-login] Выполнен вход в {registry}.", - "zh": "[docker-login] 已登录到 {registry}。" - }, - "[docker-login] Login to {registry} failed (continuing).": { - "en": "[docker-login] Login to {registry} failed (continuing).", - "bg": "[docker-login] Влизането в {registry} не успя (продължава).", - "de": "[docker-login] Anmeldung bei {registry} fehlgeschlagen (wird fortgesetzt).", - "pl": "[docker-login] Logowanie do {registry} nie powiodło się (kontynuowanie).", - "ru": "[docker-login] Ошибка входа в {registry} (продолжаем).", - "zh": "[docker-login] 登录 {registry} 失败(继续)。" - }, - "[docker-login] Skipping {registry} (token {env} not set).": { - "en": "[docker-login] Skipping {registry} (token {env} not set).", - "bg": "[docker-login] Пропускане на {registry} (токен {env} не е зададен).", - "de": "[docker-login] {registry} übersprungen (Token {env} nicht gesetzt).", - "pl": "[docker-login] Pomijanie {registry} (token {env} nie ustawiony).", - "ru": "[docker-login] Пропуск {registry} (токен {env} не задан).", - "zh": "[docker-login] 跳过 {registry}(未设置令牌 {env})。" - }, - "{env} is not set. Set it in your .env file.": { - "en": "{env} is not set. Set it in your .env file.", - "bg": "{env} не е зададен. Задайте го във вашия .env файл.", - "de": "{env} ist nicht gesetzt. Setzen Sie es in Ihrer .env-Datei.", - "pl": "{env} nie jest ustawiony. Ustaw go w pliku .env.", - "ru": "{env} не задан. Установите его в файле .env.", - "zh": "{env} 未设置。请在 .env 文件中设置。" - }, "{env} is not set. Set it in your .env file or pass it as an environment variable.": { "en": "{env} is not set. Set it in your .env file or pass it as an environment variable.", "bg": "{env} не е зададен. Задайте го във вашия .env файл или го подайте като променлива на средата.", @@ -3175,188 +3527,36 @@ "ru": "{env} не задан. Установите его в файле .env или передайте как переменную окружения.", "zh": "{env} 未设置。请在 .env 文件中设置或作为环境变量传递。" }, - "Login to {registry} failed: {error}": { - "en": "Login to {registry} failed: {error}", - "bg": "Влизането в {registry} не успя: {error}", - "de": "Anmeldung bei {registry} fehlgeschlagen: {error}", - "pl": "Logowanie do {registry} nie powiodło się: {error}", - "ru": "Ошибка входа в {registry}: {error}", - "zh": "登录 {registry} 失败: {error}" + "{env} is not set. Set it in your .env file.": { + "en": "{env} is not set. Set it in your .env file.", + "bg": "{env} не е зададен. Задайте го във вашия .env файл.", + "de": "{env} ist nicht gesetzt. Setzen Sie es in Ihrer .env-Datei.", + "pl": "{env} nie jest ustawiony. Ustaw go w pliku .env.", + "ru": "{env} не задан. Установите его в файле .env.", + "zh": "{env} 未设置。请在 .env 文件中设置。" }, - "tofu command failed in {dir}: {error}": { - "en": "tofu command failed in {dir}: {error}", - "bg": "командата tofu не успя в {dir}: {error}", - "de": "tofu-Befehl fehlgeschlagen in {dir}: {error}", - "pl": "polecenie tofu nie powiodło się w {dir}: {error}", - "ru": "команда tofu не удалась в {dir}: {error}", - "zh": "tofu 命令在 {dir} 中失败: {error}" + "{file} already exists. Use --force to overwrite.": { + "bg": "{file} already exists. Use --force to overwrite.", + "de": "{file} already exists. Use --force to overwrite.", + "en": "{file} already exists. Use --force to overwrite.", + "pl": "{file} już istnieje. Użyj --force, aby nadpisać.", + "ru": "{file} already exists. Use --force to overwrite.", + "zh": "{file} already exists. Use --force to overwrite." }, - "WARN: .venv has Python {version}, but >={req} is required.": { - "en": "WARN: .venv has Python {version}, but >={req} is required.", - "bg": "ПРЕДУПРЕЖДЕНИЕ: .venv има Python {version}, но се изисква >={req}.", - "de": "WARNUNG: .venv hat Python {version}, aber >={req} ist erforderlich.", - "pl": "OSTRZEŻENIE: .venv ma Python {version}, ale wymagane jest >={req}.", - "ru": "ПРЕДУПРЕЖДЕНИЕ: в .venv установлен Python {version}, но требуется >={req}.", - "zh": "警告: .venv 的 Python 版本为 {version},但要求 >={req}。" + "{level}: {tool} not found.{hint}": { + "en": "{level}: {tool} not found.{hint}", + "bg": "{level}: {tool} не е намерен.{hint}", + "de": "{level}: {tool} nicht gefunden.{hint}", + "pl": "{level}: {tool} nie znaleziono.{hint}", + "ru": "{level}: {tool} не найден.{hint}", + "zh": "{level}: 未找到 {tool}。{hint}" }, - " -> {dir}": { - "en": " -> {dir}", - "bg": " -> {dir}", - "de": " -> {dir}", - "pl": " -> {dir}", - "ru": " -> {dir}", - "zh": " -> {dir}" - }, - "[tofu-init] Initializing {dir}...": { - "en": "[tofu-init] Initializing {dir}...", - "bg": "[tofu-init] Инициализиране на {dir}...", - "de": "[tofu-init] Initialisiere {dir}...", - "pl": "[tofu-init] Inicjalizacja {dir}...", - "ru": "[tofu-init] Инициализация {dir}...", - "zh": "[tofu-init] 正在初始化 {dir}..." - }, - "[tofu-init] Done.": { - "en": "[tofu-init] Done.", - "bg": "[tofu-init] Готово.", - "de": "[tofu-init] Fertig.", - "pl": "[tofu-init] Gotowe.", - "ru": "[tofu-init] Готово.", - "zh": "[tofu-init] 完成。" - }, - "[tofu-{mode}] Validating OpenTofu configurations...": { - "en": "[tofu-{mode}] Validating OpenTofu configurations...", - "bg": "[tofu-{mode}] Проверка на OpenTofu конфигурациите...", - "de": "[tofu-{mode}] Validiere OpenTofu-Konfigurationen...", - "pl": "[tofu-{mode}] Sprawdzanie konfiguracji OpenTofu...", - "ru": "[tofu-{mode}] Проверка конфигураций OpenTofu...", - "zh": "[tofu-{mode}] 正在验证 OpenTofu 配置..." - }, - "[tofu-{mode}] All configurations valid.": { - "en": "[tofu-{mode}] All configurations valid.", - "bg": "[tofu-{mode}] Всички конфигурации са валидни.", - "de": "[tofu-{mode}] Alle Konfigurationen gültig.", - "pl": "[tofu-{mode}] Wszystkie konfiguracje są poprawne.", - "ru": "[tofu-{mode}] Все конфигурации валидны.", - "zh": "[tofu-{mode}] 所有配置有效。" - }, - "[check-deps] Verifying tools...": { - "en": "[check-deps] Verifying tools...", - "bg": "[check-deps] Проверка на инструментите...", - "de": "[check-deps] Werkzeuge werden überprüft...", - "pl": "[check-deps] Sprawdzanie narzędzi...", - "ru": "[check-deps] Проверка инструментов...", - "zh": "[check-deps] 正在验证工具..." - }, - " {tool}: found at {path}": { - "en": " {tool}: found at {path}", - "bg": " {tool}: намерен на {path}", - "de": " {tool}: gefunden unter {path}", - "pl": " {tool}: znaleziono w {path}", - "ru": " {tool}: найден в {path}", - "zh": " {tool}: 在 {path} 找到" - }, - " Run 'make install-checkmake' to install the Makefile linter.": { - "en": " Run 'make install-checkmake' to install the Makefile linter.", - "bg": " Изпълнете 'make install-checkmake' за инсталиране на Makefile линтера.", - "de": " Führen Sie 'make install-checkmake' aus, um den Makefile-Linter zu installieren.", - "pl": " Uruchom 'make install-checkmake', aby zainstalować linter Makefile.", - "ru": " Выполните 'make install-checkmake' для установки линтера Makefile.", - "zh": " 运行 'make install-checkmake' 来安装 Makefile 检查器。" - }, - "Required tools missing.": { - "en": "Required tools missing.", - "bg": "Липсват задължителни инструменти.", - "de": "Erforderliche Werkzeuge fehlen.", - "pl": "Brak wymaganych narzędzi.", - "ru": "Отсутствуют обязательные инструменты.", - "zh": "缺少必需的工具。" - }, - "[check-deps] All core tools present.": { - "en": "[check-deps] All core tools present.", - "bg": "[check-deps] Всички основни инструменти са налични.", - "de": "[check-deps] Alle Kernwerkzeuge vorhanden.", - "pl": "[check-deps] Wszystkie podstawowe narzędzia są dostępne.", - "ru": "[check-deps] Все основные инструменты доступны.", - "zh": "[check-deps] 所有核心工具均已就绪。" - }, - "SSH_PRIVATE_KEY not set — skipping SSH key setup": { - "en": "SSH_PRIVATE_KEY not set — skipping SSH key setup", - "bg": "SSH_PRIVATE_KEY не е зададен — пропускане на SSH ключ настройката", - "de": "SSH_PRIVATE_KEY nicht gesetzt — SSH-Schlüssel-Setup übersprungen", - "pl": "SSH_PRIVATE_KEY nie ustawione — pomijanie konfiguracji klucza SSH", - "ru": "SSH_PRIVATE_KEY не задан — пропуск настройки SSH-ключа", - "zh": "SSH_PRIVATE_KEY 未设置 — 跳过 SSH 密钥设置" - }, - "Failed to start ssh-agent: {error}": { - "en": "Failed to start ssh-agent: {error}", - "bg": "Неуспешно стартиране на ssh-agent: {error}", - "de": "Starten von ssh-agent fehlgeschlagen: {error}", - "pl": "Nie udało się uruchomić ssh-agent: {error}", - "ru": "Не удалось запустить ssh-agent: {error}", - "zh": "启动 ssh-agent 失败: {error}" - }, - "SSH key set up successfully": { - "en": "SSH key set up successfully", - "bg": "SSH ключът е настроен успешно", - "de": "SSH-Schlüssel erfolgreich eingerichtet", - "pl": "Klucz SSH skonfigurowany pomyślnie", - "ru": "SSH-ключ успешно настроен", - "zh": "SSH 密钥设置成功" - }, - "SSH key setup skipped (no key provided)": { - "en": "SSH key setup skipped (no key provided)", - "bg": "Настройката на SSH ключ е пропусната (не е предоставен ключ)", - "de": "SSH-Schlüssel-Setup übersprungen (kein Schlüssel bereitgestellt)", - "pl": "Pominięto konfigurację klucza SSH (brak klucza)", - "ru": "Настройка SSH-ключа пропущена (ключ не предоставлен)", - "zh": "SSH 密钥设置已跳过(未提供密钥)" - }, - "Found {count} unsafe identity check(s) in integration tests.": { - "en": "Found {count} unsafe identity check(s) in integration tests.", - "bg": "Намерени са {count} небрежни проверки за идентичност в интеграционните тестове.", - "de": "{count} unsichere Identitätsprüfung(en) in Integrationstests gefunden.", - "pl": "Znaleziono {count} niebezpiecznych sprawdzeń tożsamości w testach integracyjnych.", - "ru": "Найдено {count} небезопасных проверок идентичности в интеграционных тестах.", - "zh": "在集成测试中发现 {count} 个不安全的身份检查。" - }, - "Use string comparison or _is_truthy()/_is_falsy() helpers instead. Add '{marker}' to suppress individual lines.": { - "en": "Use string comparison or _is_truthy()/_is_falsy() helpers instead. Add '{marker}' to suppress individual lines.", - "bg": "Използвайте сравнение на низове или _is_truthy()/_is_falsy() помощници. Добавете '{marker}' за потискане на отделни редове.", - "de": "Verwenden Sie String-Vergleich oder _is_truthy()/_is_falsy() Hilfsfunktionen. Fügen Sie '{marker}' hinzu, um einzelne Zeilen zu unterdrücken.", - "pl": "Użyj porównania ciągów lub pomocników _is_truthy()/_is_falsy(). Dodaj '{marker}', aby pominąć pojedyncze linie.", - "ru": "Используйте строковое сравнение или помощники _is_truthy()/_is_falsy(). Добавьте '{marker}' для подавления отдельных строк.", - "zh": "使用字符串比较或 _is_truthy()/_is_falsy() 辅助函数。添加 '{marker}' 以抑制个别行。" - }, - "[check-api-identity-checks] Passed: no unsafe identity checks found": { - "en": "[check-api-identity-checks] Passed: no unsafe identity checks found", - "bg": "[check-api-identity-checks] Мина: не са намерени небрежни проверки за идентичност", - "de": "[check-api-identity-checks] Bestanden: keine unsicheren Identitätsprüfungen gefunden", - "pl": "[check-api-identity-checks] Passed: nie znaleziono niebezpiecznych sprawdzeń tożsamości", - "ru": "[check-api-identity-checks] Пройдено: небезопасных проверок идентичности не найдено", - "zh": "[check-api-identity-checks] 通过:未发现不安全的身份检查" - }, - "Directory to scan (default: tests/integration). Can be repeated.": { - "en": "Directory to scan (default: tests/integration). Can be repeated.", - "bg": "Директория за сканиране (по подразбиране: tests/integration). Може да се повтаря.", - "de": "Zu scannendes Verzeichnis (Standard: tests/integration). Kann wiederholt werden.", - "pl": "Katalog do skanowania (domyślnie: tests/integration). Można powtarzać.", - "ru": "Директория для сканирования (по умолчанию: tests/integration). Можно повторять.", - "zh": "要扫描的目录(默认:tests/integration)。可重复。" - }, - "Failed to list existing wiki pages after retries: {error}. Aborting to avoid creating duplicate pages.": { - "bg": "Неуспешно извличане на съществуващи wiki страници след повторни опити: {error}. Прекратяване, за да се избегне създаване на дублирани страници.", - "de": "Abrufen bestehender Wiki-Seiten nach Wiederholungen fehlgeschlagen: {error}. Abbruch, um doppelte Seiten zu vermeiden.", - "en": "Failed to list existing wiki pages after retries: {error}. Aborting to avoid creating duplicate pages.", - "pl": "Nie udało się wylistować istniejących stron wiki po ponownych próbach: {error}. Przerywanie, aby uniknąć tworzenia zduplikowanych stron.", - "ru": "Не удалось получить список существующих wiki-страниц после повторных попыток: {error}. Прерывание, чтобы избежать создания дубликатов страниц.", - "zh": "重试后列出现有 wiki 页面失败:{error}。正在中止以避免创建重复页面。" - }, - " Page '{title}' already exists (stale list). Re-listing and updating...": { - "bg": " Страницата '{title}' вече съществува (остарял списък). Пресписване и обновяване...", - "de": " Seite '{title}' existiert bereits (veraltete Liste). Neu auflisten und aktualisieren...", - "en": " Page '{title}' already exists (stale list). Re-listing and updating...", - "pl": " Strona '{title}' już istnieje (nieaktualna lista). Ponowne listowanie i aktualizacja...", - "ru": " Страница '{title}' уже существует (устаревший список). Повторное получение списка и обновление...", - "zh": " 页面 '{title}' 已存在(列表过期)。重新列出并更新..." + "{separator}": { + "bg": "{separator}", + "de": "{separator}", + "en": "{separator}", + "pl": "{separator}", + "ru": "{separator}", + "zh": "{separator}" } } diff --git a/tests/unit/test_api_clients.py b/tests/unit/test_api_clients.py index aeb8422..d104d37 100644 --- a/tests/unit/test_api_clients.py +++ b/tests/unit/test_api_clients.py @@ -909,3 +909,65 @@ class TestGiteaClientActions: "https://git.example.com/repos/owner/repo/actions/jobs/10026/logs", timeout=DEFAULT_TIMEOUT, ) + + def test_get_repo_variable_returns_value(self) -> None: + client = GiteaClient("https://git.example.com", "tok", "owner", "repo") + client._session.request = MagicMock(return_value=_mock_response({"value": "v0.28.1"})) + result = client.get_repo_variable("PRODUCTION_DEPLOY_TAG") + assert result == "v0.28.1" + client._session.request.assert_called_once_with( + "GET", + "https://git.example.com/repos/owner/repo/actions/variables/PRODUCTION_DEPLOY_TAG", + timeout=DEFAULT_TIMEOUT, + ) + + def test_get_repo_variable_returns_none_on_404(self) -> None: + client = GiteaClient("https://git.example.com", "tok", "owner", "repo") + not_found = MagicMock() + not_found.raise_for_status.side_effect = _mock_http_error(404, "not found") + client._session.request = MagicMock(return_value=not_found) + result = client.get_repo_variable("MISSING_VAR") + assert result is None + + @patch("time.sleep") + def test_get_repo_variable_reraises_non_404(self, mock_sleep: MagicMock) -> None: + client = GiteaClient("https://git.example.com", "tok", "owner", "repo") + server_error = MagicMock() + server_error.raise_for_status.side_effect = _mock_http_error(500, "server error") + client._session.request = MagicMock(return_value=server_error) + with pytest.raises(APIError) as exc_info: + client.get_repo_variable("SOME_VAR") + assert exc_info.value.status == 500 + + def test_set_repo_variable_updates_existing(self) -> None: + client = GiteaClient("https://git.example.com", "tok", "owner", "repo") + client._session.request = MagicMock(return_value=_mock_response({})) + client.set_repo_variable("PRODUCTION_DEPLOY_TAG", "v0.28.2") + client._session.request.assert_called_once_with( + "PATCH", + "https://git.example.com/repos/owner/repo/actions/variables/PRODUCTION_DEPLOY_TAG", + timeout=DEFAULT_TIMEOUT, + json={"value": "v0.28.2"}, + ) + + def test_set_repo_variable_creates_on_404(self) -> None: + client = GiteaClient("https://git.example.com", "tok", "owner", "repo") + not_found = MagicMock() + not_found.raise_for_status.side_effect = _mock_http_error(404, "not found") + created = _mock_response({}) + client._session.request = MagicMock(side_effect=[not_found, created]) + client.set_repo_variable("NEW_VAR", "v0.29.0") + assert client._session.request.call_count == 2 + second_call = client._session.request.call_args_list[1] + assert second_call.args[0] == "POST" + assert second_call.args[1] == "https://git.example.com/repos/owner/repo/actions/variables" + assert second_call.kwargs["json"] == {"name": "NEW_VAR", "value": "v0.29.0"} + + def test_set_repo_variable_reraises_non_404(self) -> None: + client = GiteaClient("https://git.example.com", "tok", "owner", "repo") + forbidden = MagicMock() + forbidden.raise_for_status.side_effect = _mock_http_error(403, "forbidden") + client._session.request = MagicMock(return_value=forbidden) + with pytest.raises(APIError) as exc_info: + client.set_repo_variable("SOME_VAR", "val") + assert exc_info.value.status == 403