/
dgpolar
/
volga-908
Обзор
Документация
Войти
/
dgpolar
/
volga-908
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
scripts/setup_gitverse_secrets.py
122 строки
4 KB
DGPolar
Harden daily updates against temporary source gaps and refresh data.
08 июл 2026, 10:26
08 июл 2026, 10:26
4a29de3
Код
Авторство
О чём код?
#!/usr/bin/env python3 """Задаёт секреты YC_S3_* в GitVerse через Public API. Нужен API-токен (не пароль от git): Настройки → Управление токенами → Репозитории + API. Пример: export GITVERSE_TOKEN='glpat-...' export YC_S3_BUCKET='dgpolar-volga908' export YC_S3_ACCESS_KEY='YCAJ...' export YC_S3_SECRET_KEY='YCNf...' python3 scripts/setup_gitverse_secrets.py Или из локального файла (не в git): source scripts/yandex.env && export GITVERSE_TOKEN='...' python3 scripts/setup_gitverse_secrets.py """ from __future__ import annotations import base64 import json import os import sys import urllib.error import urllib.request API = "https://api.gitverse.ru" OWNER = os.environ.get("GITVERSE_OWNER", "dgpolar") REPO = os.environ.get("GITVERSE_REPO", "volga-908") SECRETS = ("YC_S3_BUCKET", "YC_S3_ACCESS_KEY", "YC_S3_SECRET_KEY") def api(method: str, path: str, token: str, body: dict | None = None) -> tuple[int, dict | str]: headers = { "Authorization": f"Bearer {token}", "Accept": "application/vnd.gitverse.object+json;version=1", } data = None if body is not None: headers["Content-Type"] = "application/json" data = json.dumps(body).encode() req = urllib.request.Request(f"{API}{path}", data=data, headers=headers, method=method) try: with urllib.request.urlopen(req, timeout=30) as resp: raw = resp.read().decode() return resp.status, json.loads(raw) if raw else {} except urllib.error.HTTPError as exc: raw = exc.read().decode() try: payload: dict | str = json.loads(raw) except json.JSONDecodeError: payload = raw return exc.code, payload def encrypt_secret(public_key_b64: str, secret: str) -> str: try: from nacl import public, encoding except ImportError as exc: raise SystemExit( "Нужен PyNaCl: pip install pynacl" ) from exc key = public.PublicKey(public_key_b64.encode("utf-8"), encoding.Base64Encoder()) sealed = public.SealedBox(key) encrypted = sealed.encrypt(secret.encode("utf-8")) return base64.b64encode(encrypted).decode("utf-8") def main() -> int: token = os.environ.get("GITVERSE_TOKEN", "").strip() if not token: print("Задайте GITVERSE_TOKEN (API-токен GitVerse)", file=sys.stderr) return 1 values = {name: os.environ.get(name, "").strip() for name in SECRETS} missing = [name for name, value in values.items() if not value] if missing: print(f"Не заданы: {', '.join(missing)}", file=sys.stderr) return 1 code, user = api("GET", "/user", token) if code != 200: print(f"Ошибка авторизации API ({code}): {user}", file=sys.stderr) return 1 print(f"Авторизация OK: {user.get('login', user)}") code, listed = api("GET", f"/repos/{OWNER}/{REPO}/actions/secrets", token) if code != 200: print(f"Не удалось получить список секретов ({code}): {listed}", file=sys.stderr) return 1 code, pubkey = api("GET", f"/repos/{OWNER}/{REPO}/actions/secrets/public-key", token) if code != 200: print(f"Не удалось получить public-key ({code}): {pubkey}", file=sys.stderr) return 1 key_id = pubkey["key_id"] public_key = pubkey["key"] for name, value in values.items(): encrypted = encrypt_secret(public_key, value) code, result = api( "PUT", f"/repos/{OWNER}/{REPO}/actions/secrets/{name}", token, {"encrypted_value": encrypted, "key_id": key_id}, ) if code not in (201, 204): print(f"Ошибка записи {name} ({code}): {result}", file=sys.stderr) return 1 print(f"✓ {name}") code, listed2 = api("GET", f"/repos/{OWNER}/{REPO}/actions/secrets", token) if code == 200: names = [s["name"] for s in listed2.get("secrets", [])] print("Секреты в репозитории:", ", ".join(sorted(names))) return 0 if __name__ == "__main__": raise SystemExit(main())