Добавлены улучшения для управления сертификатами и синхронизации Wiki

- Обновлены скрипты для поддержки групп сертификатов (SAN) в конфигурации.
- Добавлен новый скрипт для запуска GitHub Actions workflows.
- Обновлены Makefile и документация для отражения новых возможностей.
- Улучшена обработка доменов в коде и конфигурации.
This commit is contained in:
Dmitriy Fofanov
2026-02-24 23:07:36 +03:00
parent 3aacf626a3
commit 90966663bf
7 changed files with 390 additions and 73 deletions
+137
View File
@@ -0,0 +1,137 @@
#!/usr/bin/env python3
import argparse
import json
import os
import re
import sys
import urllib.error
import urllib.request
from subprocess import PIPE, run
def get_env(name: str, default: str = "") -> str:
value = os.getenv(name, default)
return value.strip() if isinstance(value, str) else default
def fail(message: str, code: int = 1) -> None:
print(f"{message}")
sys.exit(code)
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description="Dispatch Gitea Actions workflow")
parser.add_argument("--workflow", default="wiki-sync.yml", help="Workflow file name (e.g. wiki-sync.yml)")
parser.add_argument("--ref", default="master", help="Git ref for workflow dispatch")
parser.add_argument(
"--input",
action="append",
default=[],
help="Workflow input in key=value format. Can be provided multiple times.",
)
parser.add_argument(
"--require-input",
action="append",
default=[],
help="Required input key(s). Fails if key is missing or empty.",
)
return parser.parse_args()
def parse_inputs(items: list[str]) -> dict[str, str]:
result: dict[str, str] = {}
for item in items:
if "=" not in item:
fail(f"Неверный формат --input '{item}'. Используйте key=value")
key, value = item.split("=", 1)
key = key.strip()
value = value.strip()
if not key:
fail(f"Пустой ключ в --input '{item}'")
result[key] = value
return result
def get_repo_path() -> str:
result = run(["git", "config", "--get", "remote.origin.url"], stdout=PIPE, stderr=PIPE, text=True)
origin_url = (result.stdout or "").strip()
if result.returncode != 0 or not origin_url:
fail("remote.origin.url не найден. Проверьте, что команда запущена внутри git-репозитория.")
repo_path = re.sub(r"^(https?://[^/]+/|git@[^:]+:)", "", origin_url)
repo_path = re.sub(r"\.git$", "", repo_path)
if not repo_path:
fail(f"Не удалось вычислить owner/repo из remote.origin.url: {origin_url}")
return repo_path
def main() -> None:
args = parse_args()
token = get_env("DFGIT_TOKEN") or get_env("GIT_TOKEN")
if not token:
fail("не задан DFGIT_TOKEN (или GIT_TOKEN).")
dfgit_url = get_env("DFGIT_URL", "http://dfgit").rstrip("/")
workflow = args.workflow.strip() or "wiki-sync.yml"
ref = args.ref.strip() or "master"
inputs = parse_inputs(args.input)
for required_key in args.require_input:
required_key = required_key.strip()
if required_key and not inputs.get(required_key, "").strip():
fail(
f"Обязательный input '{required_key}' не задан. "
f"Передайте --input {required_key}=..."
)
repo_path = get_repo_path()
dispatch_url = f"{dfgit_url}/api/v1/repos/{repo_path}/actions/workflows/{workflow}/dispatches"
payload_data: dict[str, object] = {"ref": ref}
if inputs:
payload_data["inputs"] = inputs
payload = json.dumps(payload_data).encode("utf-8")
print(f"→ Репозиторий: {repo_path}")
print(f"→ Workflow: {workflow}, ref: {ref}")
if inputs:
print(f"→ Inputs: {json.dumps(inputs, ensure_ascii=False)}")
print(f"→ Запрос: {dispatch_url}")
request = urllib.request.Request(
dispatch_url,
data=payload,
method="POST",
headers={
"Authorization": f"token {token}",
"Content-Type": "application/json",
"Accept": "application/json",
},
)
try:
with urllib.request.urlopen(request, timeout=30) as response:
status = response.getcode()
body = response.read().decode("utf-8", errors="replace").strip()
except urllib.error.HTTPError as error:
status = error.code
body = error.read().decode("utf-8", errors="replace").strip()
except urllib.error.URLError as error:
fail(f"Ошибка сети при обращении к dfgit: {error}")
if status in (200, 201, 204):
print("✓ Workflow успешно запущен")
print("Проверьте статус в Actions на сервере dfgit.")
return
print(f"✗ Ошибка запуска workflow (HTTP {status})")
if body:
print("Ответ API:")
print(body)
sys.exit(1)
if __name__ == "__main__":
main()