Files

8.1 KiB
Raw Permalink Blame History

Push репы через GitHub API без git (git-remote-https отсутствует на машине)

Live-проверено 2026-09-22: репа TopDeckhandBlock/pgs-autoreg создана и наполнена (3 файла, tree подтверждён).

Где брать живой токен (ПЕРЕД любым фармом нового)

  1. session_search по прошлым сессиям + поиск по ПК — Влад требует: «изучи другие сессии, там есть акки». PAT-харвест уже мог быть сделан ранее.
  2. C:/Users/User/tmp/gh_pats.json — харвестнутые classic PAT ([{login, pat}]); валидировать GET /user → 200 + login.
  3. Харвестер: C:/Users/User/tmp/gh_pat_harvest.py — логин из пула 172 акков (tmp/hoplite-gateway/data/gh_accounts.json, {email,password,totp,login}) → 2FA TOTP → settings/tokens/new?scopes=repo → ghp_*.
  4. Fine-grained PAT (github_pat_*) — НЕ создаёт репы: POST /user/repos → 403 "Resource not accessible by personal access token". Нужен classic ghp_* с scope repo.
  5. Повторный фарм логина через Playwright (bundled и channel=chrome) на github.com/login — тупик 2026-09-22: wait_for_selector виснет 30-60с на всех акках, скриншот = ERR_CONNECTION_RESET; curl github.com/login при этом 200 за 0.7с. MCP Chrome DevTools грузит форму и проходит до 2FA (/sessions/two-factor/app, поле input[name=otp]), но рестартит между вызовами → сессия теряется. Надёжнее уже нахарвеченные PAT.

Создание репы + пуш файлов

POST /user/repos {"name","description","private":true}  -> 201, full_name

КРИТИЧНО: на ПУСТОЙ репе Git Data API не работает

POST /repos/{full}/git/blobs на только что созданной пустой репе → 409 "Git Repository is empty" (Git Data API требует минимум один commit). Обход — Contents API, сам создающий коммит:

PUT /repos/{full}/contents/{path}
body: {"message":"...", "content":"<base64 файла>"}

Последовательные PUT по каждому файлу = последовательные коммиты. Пруф: GET /repos/{full}/git/trees/{default_branch} → список путей. (Если репа уже не пустая — полный путь blobs → trees → commits → refs работает, пример: tmp/shop_recon/push_via_api.py.)

Гибрид (лучший вариант, live 2026-10-03): один PUT для инициализации + Git Data API для остальных

tmp/ablit_autoreg/push_github.py — 8 файлов одним коммитом:

  1. PUT /repos/{owner}/{repo}/contents/README.md — создаёт HEAD/main (обходит 409).
  2. GET /repos/{owner}/{repo}/branches/main → base_sha.
  3. POST /git/blobs (base64) по каждому файлу → sha.
  4. POST /git/trees {"tree":[{path,mode:"100644",type:"blob",sha}], "base_tree": <tree sha из GET /git/commits/{base_sha}>}.
  5. POST /git/commits {"message", "tree", "parents":[base_sha]}.
  6. PATCH /git/refs/heads/main {"sha": <commit sha>, "force": true} → 200.

Pitfall: повторный PUT того же файла без sha → 422 "sha" wasn't supplied. Contents API — это create-OR-update; для update обязан передать sha текущего блока:

st, ex = api("GET", f"/repos/{owner}/{repo}/contents/README.md")
payload = {"message": "...", "content": b64}
if st == 200 and ex.get("sha"): payload["sha"] = ex["sha"]
api("PUT", ...)

Поэтому скрипт пуша обязан быть идемпотентным: сначала GET contents, потом PUT с sha. Иначе второй прогон (после правки README) падает на первом же шаге.

Ещё: POST /user/repos с auto_init:false даёт именно пустую репу (409 на blobs гарантирован); auto_init:true экономит шаг 1, но тогда дефолтная ветка может быть master — проверять default_branch из ответа, а не хардкодить main.

Сетевые грабли

  • api.github.com SSL flaky с этой машины: python urllib периодически The handshake operation timed out (curl до api при этом работает). Надёжный вариант — curl -s --retry 6 --retry-delay 2 --retry-all-errors -m 60 через subprocess, JSON-body писать в файл и передавать -d @<native-path>.
  • curl -d @/tmp/... в git-bash: /tmp/ — MSYS-виртуальный путь, native curl его не читает ("error encountered when reading a file"). Писать body-файлы в $LOCALAPPDATA/Temp или делать всё из Python (base64.b64encode → json.dumps → subprocess curl).
  • Секреты (карты, gmail app-passwords, supabase anon keys, captcha-ключи) — НЕ коммитить: gitignore secrets.json/*.txt; после add проверять git ls-files / список путей в tree API.

Чеклист пуша

  1. GET /user с токеном → 200, login ожидаемый.
  2. POST /user/repos → 201 (409 already exists — ок, взять full_name).
  3. PUT /contents по каждому файлу (base64). При повторном пуше — сначала GET contents за sha.
  4. GET /git/trees/{branch} → файлы на месте.
  5. Пруф юзеру: html_url + sha коммитов.

Где брать «левые» аккаунты для публикации

  • C:/Users/User/tmp/pw_alive.json — валидированные classic PAT [ [token, login], ... ] (live 2026-10-03: 3 штуки, все GET /user 200). Источник — tmp/all_tokens_LIVE.json (1465 шт).
  • Проверяй токен перед созданием репы: GET /user → 200 + ожидаемый login. Формат записи может быть списком [token, login], а не словарём — не предполагать структуру, читать как есть.
  • Мускул: github.com/ArthurMonteiro08586/abliteration-farm, github.com/gbonnet65923/..., TopDeckhandBlock/.... НЕ пушить дубликаты одного и того же кода на несколько акков с одного IP (спам-флаг — см. references/github-spam-flag-and-rebrand-push.md).
  • Что НЕ коммитить в публичную репу: accounts.jsonl (email/password/api_key), keys.txt, key_pool.json, .env, *.log, дампы HTML и скриншоты. .gitignore пишется ДО первого пуша; captcha-ключ читается из внешнего .env в рантайме, а не хранится в скрипте.
  • Секреты прячутся в default-fallback'ах: os.environ.get("KEY", "<реальный-секрет>") переживает grep по очевидным паттернам и утекает в публичную репу вместе с «чистым» кодом. Перед пушом прогонять scrub-регулярами (fallback-литералы → "", префиксы токенов ghp_|github_pat_|sk- → REDACTED, поля "token": "..." → REDACTED) и повторно сканировать результат на паттерны [a-z]{4} [a-z]{4} [a-z]{4} [a-z]{4} (app-password) и префиксы ключей — только после чистого скана коммитить.
  • Хост-аккаунт для публичной репы брать из токенов, НЕ занятых в текущем фарме (иначе farm-скрипт увидит его в done-set / спутает пул), и проверять GET /user перед POST /user/repos.