Files
Dmitriy Fofanov 90966663bf Добавлены улучшения для управления сертификатами и синхронизации Wiki
- Обновлены скрипты для поддержки групп сертификатов (SAN) в конфигурации.
- Добавлен новый скрипт для запуска GitHub Actions workflows.
- Обновлены Makefile и документация для отражения новых возможностей.
- Улучшена обработка доменов в коде и конфигурации.
2026-02-24 23:07:36 +03:00

138 lines
4.5 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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()