mirror of
https://gitverse.ru/kpa39l/project-git-setup.git
synced 2026-09-29 09:15:06 +00:00
Initial commit: Hermes skill project-git-setup
This commit is contained in:
@@ -0,0 +1,142 @@
|
|||||||
|
---
|
||||||
|
name: project-git-setup
|
||||||
|
title: "Git-инициализация нового проекта (gitverse.ru + gitea pull-mirror)"
|
||||||
|
description: "Use when setting up git for a new project."
|
||||||
|
version: 1.0.0
|
||||||
|
author: hermes
|
||||||
|
license: MIT
|
||||||
|
---
|
||||||
|
|
||||||
|
# Git-инициализация нового проекта
|
||||||
|
|
||||||
|
## When to Use
|
||||||
|
|
||||||
|
Любой новый проект или перевод существующего каталога под git — сразу после
|
||||||
|
создания проекта (даже «пустого», с одним README). Схема: локальный git →
|
||||||
|
**приватный** репозиторий на gitverse.ru (истина) → **pull mirror** в gitea.nixg.ru
|
||||||
|
(локальная резервная копия, синхронизация каждые **12 часов** = 2 раза в сутки).
|
||||||
|
|
||||||
|
## Триггеры
|
||||||
|
|
||||||
|
- «новый проект», «заведи git», «инициализируй репозиторий»
|
||||||
|
- Создание проекта, который будет жить в `/opt/<name>` (стандарт окружения — всё в /opt)
|
||||||
|
|
||||||
|
## Шаг 0. Собрать факты
|
||||||
|
|
||||||
|
- Имя репозитория: lowercase, дефисы (`tproxy-web`, `monitoring`, `openspec-lab`)
|
||||||
|
- Путь проекта (обычно `/opt/<name>`)
|
||||||
|
- Стек: есть ли `Dockerfile` / `docker-compose.yml` / `compose.yaml`? Node/Python/Go?
|
||||||
|
- Существующий `.gitignore` (дополнить, не затирать)
|
||||||
|
|
||||||
|
## Токены — только из настроек (НИКОГДА не искать по каталогам)
|
||||||
|
|
||||||
|
Единый источник: **`/opt/hermes/.hermes/secrets/git-tokens.env`** (chmod 600).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
source /opt/hermes/.hermes/secrets/git-tokens.env
|
||||||
|
# → GITVERSE_LOGIN, GITVERSE_PAT, GITVERSE_API, GITEA_API, GITEA_TOKEN
|
||||||
|
```
|
||||||
|
|
||||||
|
Если файла нет — создать по образцу (значения брать из obsidian
|
||||||
|
`homelab/gitea.nixg.ru/Gitverse mirror token.md` ИЛИ из URL существующего mirror:
|
||||||
|
`docker exec gitea cat /data/git/repositories/estorozhenko/<repo>.git/config`),
|
||||||
|
затем записать в secrets и chmod 600.
|
||||||
|
|
||||||
|
**Правила:**
|
||||||
|
- Токены в коде/README/коммитах не хранить. В `.gitignore` всех проектов — строка `secrets/`.
|
||||||
|
- Внутри скиллов и reference — только плейсхолдеры `<PAT>`/${GITVERSE_PAT}, не значения.
|
||||||
|
- Новый токен создаётся один раз, кладётся в secrets файл, дальше только `source`.
|
||||||
|
|
||||||
|
## Шаг 1. .gitignore
|
||||||
|
|
||||||
|
Шаблон `templates/docker-gitignore.md` использовать если в проекте есть docker
|
||||||
|
(compose/Dockerfile — почти всегда в наших проектах). Для не-docker проектов — базовый
|
||||||
|
шаблон оттуда без docker-секции. Дополнить спецификой стека (секции Python/Node/Go в шаблоне).
|
||||||
|
**НИКОГДА не игнорить**: `docker-compose*.yml`, `Dockerfile*`, `README*`, `*.md`, `*.yml` конфиги, план/статус-файлы (PLAN.md, STATUS.md, TODO.md).
|
||||||
|
|
||||||
|
## Шаг 2. Локальный git
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /opt/<name>
|
||||||
|
git init
|
||||||
|
git config user.name "estorozhenko" # если не задан глобально
|
||||||
|
git config user.email "estorozhenko@nixg.ru"
|
||||||
|
git add -A
|
||||||
|
git commit -m "Initial commit"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Шаг 3. Создать ПРИВАТНЫЙ репозиторий на gitverse.ru
|
||||||
|
|
||||||
|
```bash
|
||||||
|
source /opt/hermes/.hermes/secrets/git-tokens.env
|
||||||
|
# проверить логин (реальный аккаунт — kpa39l, НЕ estorozhenko!)
|
||||||
|
curl -s -H "Authorization: Bearer $GITVERSE_PAT" \
|
||||||
|
-H "Accept: application/vnd.gitverse.object+json;version=1" \
|
||||||
|
"$GITVERSE_API/user"
|
||||||
|
# создать репо: private:true ОБЯЗАТЕЛЬНО, auto_init:false (иначе push упадёт)
|
||||||
|
curl -s -X POST "$GITVERSE_API/user/repos" \
|
||||||
|
-H "Authorization: Bearer $GITVERSE_PAT" \
|
||||||
|
-H "Accept: application/vnd.gitverse.object+json;version=1" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d "{\"name\":\"<repo>\",\"description\":\"<описание>\",\"private\":true,\"auto_init\":false}"
|
||||||
|
```
|
||||||
|
|
||||||
|
HTTP 201 = создан; 409 = уже существует.
|
||||||
|
|
||||||
|
## Шаг 4. Push на gitverse
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git remote add origin "https://$GITVERSE_LOGIN:$GITVERSE_PAT@gitverse.ru/$GITVERSE_LOGIN/<repo>.git"
|
||||||
|
git push -u origin <текущая-ветка>
|
||||||
|
```
|
||||||
|
|
||||||
|
Ветку НЕ переименовывать без явной команды пользователя (в разных проектах уже master и main — сохранять как есть).
|
||||||
|
|
||||||
|
## Шаг 5. Pull mirror в gitea (синхронизация 2 раза в сутки)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
source /opt/hermes/.hermes/secrets/git-tokens.env
|
||||||
|
# токен gitea уже в GITEA_TOKEN; при необходимости перевыпустить:
|
||||||
|
# docker exec -u 1000 gitea gitea admin user generate-access-token \
|
||||||
|
# --username estorozhenko --token-name <repo>-mirror \
|
||||||
|
# --scopes "read:repository,write:repository,read:user,write:user" --raw
|
||||||
|
# и обновить GITEA_TOKEN в secrets/git-tokens.env
|
||||||
|
|
||||||
|
curl -X POST "$GITEA_API/repos/migrate" \
|
||||||
|
-H "Authorization: token $GITEA_TOKEN" -H "Content-Type: application/json" \
|
||||||
|
-d "{\"clone_addr\":\"https://oauth2:$GITVERSE_PAT@gitverse.ru/$GITVERSE_LOGIN/<repo>.git\",
|
||||||
|
\"repo_name\":\"<repo>\",\"repo_owner\":\"estorozhenko\",\"service\":\"git\",
|
||||||
|
\"mirror\":true,\"mirror_interval\":\"12h\"}"
|
||||||
|
```
|
||||||
|
|
||||||
|
HTTP 201 = mirror создан, интервал 12h = два раза в сутки.
|
||||||
|
|
||||||
|
## Шаг 6. Проверка (обязательно)
|
||||||
|
|
||||||
|
1. HEAD совпадает:
|
||||||
|
```bash
|
||||||
|
source /opt/hermes/.hermes/secrets/git-tokens.env
|
||||||
|
git ls-remote "https://oauth2:$GITVERSE_PAT@gitverse.ru/$GITVERSE_LOGIN/<repo>.git" HEAD
|
||||||
|
docker exec gitea git --git-dir=/data/git/repositories/estorozhenko/<repo>.git rev-parse HEAD
|
||||||
|
```
|
||||||
|
2. Принудительная синхронизация:
|
||||||
|
```bash
|
||||||
|
curl -X POST "$GITEA_API/repos/estorozhenko/<repo>/mirror-sync" \
|
||||||
|
-H "Authorization: token $GITEA_TOKEN" # → 200
|
||||||
|
```
|
||||||
|
|
||||||
|
После этого работать как обычно: `git commit` + `git push`; mirror подтянет изменения автоматически через ≤12ч.
|
||||||
|
|
||||||
|
## Питфолы (проверено на практике)
|
||||||
|
|
||||||
|
- **База gitverse API — `https://api.gitverse.ru`**, НЕ `gitverse.ru/api/v1/...` (тот путь отдаёт HTML Next.js SPA, не JSON).
|
||||||
|
- Gitea migrate **с ssh:// всегда 422** — только `https://oauth2:<PAT>@gitverse.ru/...`. Настраивать SSH-протокол в MIGRATIONS_ALLOWED_PROTOCOLS бесполезно (известный баг, не листать заново).
|
||||||
|
- `auto_init: false` — иначе gitverse создаёт свой README, и первый push падает (non-fast-forward).
|
||||||
|
- `private: true` — требование пользователя, не забывать.
|
||||||
|
- `mirror_interval: "12h"` = два раза в сутки; "8h" не подходит по ТЗ.
|
||||||
|
- Токены не хранить в коде/README/коммитах — только в remote URL и переменных сессии.
|
||||||
|
|
||||||
|
## Связанные навыки
|
||||||
|
|
||||||
|
- `git-forge-management` — общие операции с gitverse/gitea, references `gitea-pull-mirror-gitverse.md`, `gitverse-api.md`
|
||||||
|
- `github-repo-management` — для GitHub (gh CLI)
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
# Шаблон .gitignore для проектов с Docker
|
||||||
|
|
||||||
|
Секция docker — базовый минимум. Секции Python/Node/Go — добавить по стеку.
|
||||||
|
**НИКОГДА не игнорировать**: `docker-compose*.yml`, `compose*.yaml`, `Dockerfile*`, `README*`, `*.md`, `*.yml`/`*.yaml` (конфиги), `PLAN.md`, `STATUS.md`, `TODO.md`.
|
||||||
|
|
||||||
|
## Docker (всегда, если есть compose/Dockerfile)
|
||||||
|
|
||||||
|
```
|
||||||
|
# --- Docker ---
|
||||||
|
*.pid
|
||||||
|
*.seed
|
||||||
|
*.sock
|
||||||
|
*.swp
|
||||||
|
.dockerignore-tmp
|
||||||
|
```
|
||||||
|
|
||||||
|
> НЕ игнорировать `docker-compose*.yml` — это источник истины деплоя, он в git.
|
||||||
|
> Пропускать `.env*` только если они содержат секреты; `.env.example` — в git.
|
||||||
|
|
||||||
|
## Python (pip/venv/poetry)
|
||||||
|
|
||||||
|
```
|
||||||
|
# --- Python ---
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
*.egg-info/
|
||||||
|
.eggs/
|
||||||
|
build/
|
||||||
|
dist/
|
||||||
|
.venv/
|
||||||
|
venv/
|
||||||
|
env/
|
||||||
|
.env
|
||||||
|
.pytest_cache/
|
||||||
|
.mypy_cache/
|
||||||
|
.ruff_cache/
|
||||||
|
.coverage
|
||||||
|
htmlcov/
|
||||||
|
.tox/
|
||||||
|
.uv/
|
||||||
|
.ipynb_checkpoints/
|
||||||
|
```
|
||||||
|
|
||||||
|
## Node (npm/yarn/pnpm)
|
||||||
|
|
||||||
|
```
|
||||||
|
# --- Node ---
|
||||||
|
node_modules/
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
dist/
|
||||||
|
build/
|
||||||
|
coverage/
|
||||||
|
.env.local
|
||||||
|
.env.*.local
|
||||||
|
.next/
|
||||||
|
out/
|
||||||
|
```
|
||||||
|
|
||||||
|
## Go
|
||||||
|
|
||||||
|
```
|
||||||
|
# --- Go ---
|
||||||
|
/bin/
|
||||||
|
*.exe
|
||||||
|
*.test
|
||||||
|
*.out
|
||||||
|
coverage.out
|
||||||
|
```
|
||||||
|
|
||||||
|
## Универсальное (всегда)
|
||||||
|
|
||||||
|
```
|
||||||
|
# --- OS / редакторы ---
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
*~
|
||||||
|
.idea/
|
||||||
|
.vscode/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
|
||||||
|
# --- Логи / временное ---
|
||||||
|
*.log
|
||||||
|
logs/
|
||||||
|
tmp/
|
||||||
|
temp/
|
||||||
|
```
|
||||||
|
|
||||||
|
## Правило проверки
|
||||||
|
|
||||||
|
Перед `git add -A` проверить `git status` — в списке не должно быть секретов,
|
||||||
|
venv/node_modules, бинарников. Если `.env` реальный с секретами — решение по
|
||||||
|
включению/исключению явно согласовать с пользователем (по умолчанию: игнорить,
|
||||||
|
`.env.example` с заглушками фиксировать в git).
|
||||||
Reference in New Issue
Block a user