mirror of
https://github.com/Direct-Dev-Ru/go-lcg.git
synced 2025-11-16 01:29:55 +00:00
before add feature v - verbose
This commit is contained in:
235
USAGE_GUIDE.md
Normal file
235
USAGE_GUIDE.md
Normal file
@@ -0,0 +1,235 @@
|
|||||||
|
# Руководство по использованию (USAGE_GUIDE)
|
||||||
|
|
||||||
|
## Что это
|
||||||
|
|
||||||
|
Linux Command GPT (`lcg`) преобразует описание на естественном языке в готовую Linux‑команду. Инструмент поддерживает сменные провайдеры LLM (Ollama или Proxy), управление системными промптами, историю за сессию, сохранение результатов и интерактивные действия над сгенерированной командой.
|
||||||
|
|
||||||
|
## Требования
|
||||||
|
|
||||||
|
- Установленный Go (для сборки из исходников) или готовый бинарник.
|
||||||
|
- Для функции «скопировать в буфер обмена»: установите `xclip` или `xsel`.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Debian/Ubuntu
|
||||||
|
sudo apt-get install xclip
|
||||||
|
# или
|
||||||
|
sudo apt-get install xsel
|
||||||
|
```
|
||||||
|
|
||||||
|
## Установка
|
||||||
|
|
||||||
|
Сборка из исходников:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone --depth 1 https://github.com/asrul10/linux-command-gpt.git ~/.linux-command-gpt
|
||||||
|
cd ~/.linux-command-gpt
|
||||||
|
go build -o lcg
|
||||||
|
|
||||||
|
# Добавьте бинарник в PATH
|
||||||
|
ln -s ~/.linux-command-gpt/lcg ~/.local/bin
|
||||||
|
```
|
||||||
|
|
||||||
|
Или скачайте готовый бинарник из раздела релизов.
|
||||||
|
|
||||||
|
## Быстрый старт
|
||||||
|
|
||||||
|
Простой запрос:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
lcg "хочу извлечь файл linux-command-gpt.tar.gz"
|
||||||
|
```
|
||||||
|
|
||||||
|
Смешанный ввод: часть из файла, часть — текстом:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
lcg --file /path/to/context.txt "хочу вывести список директорий с помощью ls"
|
||||||
|
```
|
||||||
|
|
||||||
|
После генерации вы увидите:
|
||||||
|
|
||||||
|
```text
|
||||||
|
🤖 Запрос: <ваше описание>
|
||||||
|
✅ Выполнено за X.XX сек
|
||||||
|
|
||||||
|
📋 Команда:
|
||||||
|
<сгенерированная команда>
|
||||||
|
|
||||||
|
Действия: (c)копировать, (s)сохранить, (r)перегенерировать, (e)выполнить, (n)ничего:
|
||||||
|
```
|
||||||
|
|
||||||
|
## Переменные окружения
|
||||||
|
|
||||||
|
Можно настроить поведение без изменения командной строки.
|
||||||
|
|
||||||
|
| Переменная | Значение по умолчанию | Назначение |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `LCG_HOST` | `http://192.168.87.108:11434/` | Базовый URL API провайдера (для Ollama поставьте, например, `http://localhost:11434/`). |
|
||||||
|
| `LCG_COMPLETIONS_PATH` | `api/chat` | Относительный путь эндпоинта для Ollama. |
|
||||||
|
| `LCG_MODEL` | `codegeex4` | Имя модели у выбранного провайдера. |
|
||||||
|
| `LCG_PROMPT` | См. значение в коде | Содержимое системного промпта по умолчанию. |
|
||||||
|
| `LCG_API_KEY_FILE` | `.openai_api_key` | Файл с API‑ключом (для Ollama/Proxy не требуется). |
|
||||||
|
| `LCG_RESULT_FOLDER` | `$(pwd)/gpt_results` | Папка для сохранения результатов. |
|
||||||
|
| `LCG_PROVIDER` | `ollama` | Тип провайдера: `ollama` или `proxy`. |
|
||||||
|
| `LCG_JWT_TOKEN` | пусто | JWT токен для `proxy` провайдера (альтернатива — файл `~/.proxy_jwt_token`). |
|
||||||
|
| `LCG_PROMPT_ID` | `1` | ID системного промпта по умолчанию. |
|
||||||
|
| `LCG_TIMEOUT` | `120` | Таймаут запроса в секундах. |
|
||||||
|
|
||||||
|
Примеры настройки:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Ollama
|
||||||
|
export LCG_PROVIDER=ollama
|
||||||
|
export LCG_HOST=http://localhost:11434/
|
||||||
|
export LCG_MODEL=codegeex4
|
||||||
|
|
||||||
|
# Proxy
|
||||||
|
export LCG_PROVIDER=proxy
|
||||||
|
export LCG_HOST=http://localhost:8080
|
||||||
|
export LCG_MODEL=GigaChat-2
|
||||||
|
export LCG_JWT_TOKEN=your_jwt_token_here
|
||||||
|
```
|
||||||
|
|
||||||
|
## Базовый синтаксис
|
||||||
|
|
||||||
|
```bash
|
||||||
|
lcg [глобальные опции] <описание команды>
|
||||||
|
```
|
||||||
|
|
||||||
|
Глобальные опции:
|
||||||
|
|
||||||
|
- `--file, -f string` — прочитать часть запроса из файла и добавить к описанию.
|
||||||
|
- `--sys, -s string` — системный промпт (содержимое или ID как строка). Если не задан, используется `--prompt-id` или `LCG_PROMPT`.
|
||||||
|
- `--prompt-id, --pid int` — ID системного промпта (1–5 для стандартных, либо ваш кастомный ID).
|
||||||
|
- `--timeout, -t int` — таймаут запроса в секундах (по умолчанию 120).
|
||||||
|
- `--version, -v` — вывести версию.
|
||||||
|
- `--help, -h` — помощь.
|
||||||
|
|
||||||
|
## Подкоманды
|
||||||
|
|
||||||
|
- `lcg update-key` (`-u`): обновить API‑ключ. Для `ollama` и `proxy` не требуется — команда сообщит, что ключ не нужен.
|
||||||
|
- `lcg delete-key` (`-d`): удалить API‑ключ (не требуется для `ollama`/`proxy`).
|
||||||
|
- `lcg update-jwt` (`-j`): обновить JWT для `proxy`. Токен будет сохранён в `~/.proxy_jwt_token` (права `0600`).
|
||||||
|
- `lcg delete-jwt` (`-dj`): удалить JWT файл для `proxy`.
|
||||||
|
- `lcg models` (`-m`): показать доступные модели у текущего провайдера.
|
||||||
|
- `lcg health` (`-he`): проверить доступность API провайдера.
|
||||||
|
- `lcg config` (`-co`): показать текущую конфигурацию и состояние JWT.
|
||||||
|
- `lcg history` (`-hist`): показать историю запросов за текущий запуск (до 100 записей, не сохраняется между запусками).
|
||||||
|
- `lcg prompts ...` (`-p`): управление системными промптами:
|
||||||
|
- `lcg prompts list` (`-l`) — список всех промптов.
|
||||||
|
- `lcg prompts add` (`-a`) — добавить пользовательский промпт (по шагам в интерактиве).
|
||||||
|
- `lcg prompts delete <id>` (`-d`) — удалить пользовательский промпт по ID (>5).
|
||||||
|
- `lcg test-prompt <prompt-id> <описание>` (`-tp`): показать детали выбранного системного промпта и протестировать его на заданном описании.
|
||||||
|
|
||||||
|
## Провайдеры
|
||||||
|
|
||||||
|
### Ollama (`LCG_PROVIDER=ollama`)
|
||||||
|
|
||||||
|
- Требуется запущенный Ollama API (`LCG_HOST`, например `http://localhost:11434/`).
|
||||||
|
- `models`, `health` и генерация используют REST Ollama (`/api/tags`, `/api/chat`).
|
||||||
|
- API‑ключ не нужен.
|
||||||
|
|
||||||
|
### Proxy (`LCG_PROVIDER=proxy`)
|
||||||
|
|
||||||
|
- Требуется доступ к прокси‑серверу (`LCG_HOST`) и JWT (`LCG_JWT_TOKEN` или файл `~/.proxy_jwt_token`).
|
||||||
|
- Основные эндпоинты: `/api/v1/protected/sberchat/chat` и `/api/v1/protected/sberchat/health`.
|
||||||
|
- Команды `update-jwt`/`delete-jwt` помогают управлять токеном локально.
|
||||||
|
|
||||||
|
## Системные промпты
|
||||||
|
|
||||||
|
Встроенные (ID 1–5):
|
||||||
|
|
||||||
|
| ID | Name | Описание |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| 1 | linux-command | «Ответь только Linux‑командой, без форматирования и объяснений». |
|
||||||
|
| 2 | linux-command-with-explanation | Сгенерируй команду и кратко объясни, что она делает (формат: COMMAND: explanation). |
|
||||||
|
| 3 | linux-command-safe | Безопасные команды (без потери данных). Вывод — только команда. |
|
||||||
|
| 4 | linux-command-verbose | Команда с подробными объяснениями флагов и альтернатив. |
|
||||||
|
| 5 | linux-command-simple | Простые команды, избегать сложных опций. |
|
||||||
|
|
||||||
|
Пользовательские промпты сохраняются в `~/.lcg_prompts.json` и доступны между запусками.
|
||||||
|
|
||||||
|
## Сохранение результатов
|
||||||
|
|
||||||
|
При выборе действия `s` ответ сохраняется в `LCG_RESULT_FOLDER` (по умолчанию: `./gpt_results`) в файл вида:
|
||||||
|
|
||||||
|
```text
|
||||||
|
gpt_request_<MODEL>_YYYY-MM-DD_HH-MM-SS.md
|
||||||
|
```
|
||||||
|
|
||||||
|
Структура файла:
|
||||||
|
|
||||||
|
- `## Prompt:` — ваш запрос (включая системный промпт).
|
||||||
|
- `## Response:` — полученный ответ.
|
||||||
|
|
||||||
|
## Выполнение сгенерированной команды
|
||||||
|
|
||||||
|
Действие `e` запустит команду через `bash -c`. Перед запуском потребуется подтверждение `y/yes`. Всегда проверяйте команду вручную, особенно при операциях с файлами и сетью.
|
||||||
|
|
||||||
|
## Примеры
|
||||||
|
|
||||||
|
1. Базовый запрос с Ollama:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export LCG_PROVIDER=ollama
|
||||||
|
export LCG_HOST=http://localhost:11434/
|
||||||
|
export LCG_MODEL=codegeex4
|
||||||
|
|
||||||
|
lcg "хочу извлечь linux-command-gpt.tar.gz"
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Полный ответ от LLM (пример настройки):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
LCG_PROMPT='Provide full response' LCG_MODEL=codellama:13b \
|
||||||
|
lcg 'i need bash script to execute command by ssh on array of hosts'
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Proxy‑провайдер:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export LCG_PROVIDER=proxy
|
||||||
|
export LCG_HOST=http://localhost:8080
|
||||||
|
export LCG_MODEL=GigaChat-2
|
||||||
|
export LCG_JWT_TOKEN=your_jwt_token_here
|
||||||
|
|
||||||
|
lcg "I want to extract linux-command-gpt.tar.gz file"
|
||||||
|
|
||||||
|
lcg health
|
||||||
|
lcg config
|
||||||
|
lcg update-jwt
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Работа с файлами и промптами:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
lcg --file ./context.txt "сгенерируй команду jq для выборки поля name"
|
||||||
|
lcg --prompt-id 2 "удали все *.tmp в текущем каталоге"
|
||||||
|
lcg --sys 1 "показать размер каталога в человеко‑читаемом виде"
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Диагностика и модели:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
lcg health
|
||||||
|
lcg models
|
||||||
|
```
|
||||||
|
|
||||||
|
## История
|
||||||
|
|
||||||
|
`lcg history` выводит историю текущего процесса (не сохраняется между запусками, максимум 100 записей):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
lcg history
|
||||||
|
```
|
||||||
|
|
||||||
|
## Типичные проблемы
|
||||||
|
|
||||||
|
- Нет ответа/таймаут: увеличьте `--timeout` или `LCG_TIMEOUT`, проверьте `LCG_HOST` и сетевую доступность.
|
||||||
|
- `health` падает: проверьте, что провайдер запущен и URL верный; для `proxy` — что JWT валиден (`lcg config`).
|
||||||
|
- Копирование не работает: установите `xclip` или `xsel`.
|
||||||
|
- Нет допуска к папке результатов: настройте `LCG_RESULT_FOLDER` или права доступа.
|
||||||
|
- Для `ollama`/`proxy` API‑ключ не нужен; команды `update-key`/`delete-key` просто уведомят об этом.
|
||||||
|
|
||||||
|
## Лицензия и исходники
|
||||||
|
|
||||||
|
См. README и репозиторий проекта. Предложения и баг‑репорты приветствуются в Issues.
|
||||||
5
shell-code/pre-release.sh
Normal file
5
shell-code/pre-release.sh
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
go-ansible-vault -i shell-code/build.env -a get -m GITHUB_TOKEN > /tmp/source && source /tmp/source
|
||||||
|
|
||||||
|
GITHUB_TOKEN=$GITHUB_TOKEN python3 shell-code/release.py
|
||||||
203
shell-code/release.py
Normal file
203
shell-code/release.py
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Скрипт для создания релиза на GitHub
|
||||||
|
Использование: GITHUB_TOKEN=your_token python3 release.py
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import json
|
||||||
|
import requests
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
# Цвета для вывода
|
||||||
|
class Colors:
|
||||||
|
RED = '\033[0;31m'
|
||||||
|
GREEN = '\033[0;32m'
|
||||||
|
YELLOW = '\033[1;33m'
|
||||||
|
BLUE = '\033[0;34m'
|
||||||
|
NC = '\033[0m' # No Color
|
||||||
|
|
||||||
|
def log(message):
|
||||||
|
print(f"{Colors.GREEN}[INFO]{Colors.NC} {message}")
|
||||||
|
|
||||||
|
def error(message):
|
||||||
|
print(f"{Colors.RED}[ERROR]{Colors.NC} {message}", file=sys.stderr)
|
||||||
|
|
||||||
|
def warn(message):
|
||||||
|
print(f"{Colors.YELLOW}[WARN]{Colors.NC} {message}")
|
||||||
|
|
||||||
|
def debug(message):
|
||||||
|
print(f"{Colors.BLUE}[DEBUG]{Colors.NC} {message}")
|
||||||
|
|
||||||
|
# Конфигурация
|
||||||
|
REPO = "direct-dev-ru/go-lcg"
|
||||||
|
VERSION_FILE = "VERSION.txt"
|
||||||
|
BINARIES_DIR = "binaries-for-upload"
|
||||||
|
|
||||||
|
def check_environment():
|
||||||
|
"""Проверка переменных окружения"""
|
||||||
|
token = os.getenv('GITHUB_TOKEN')
|
||||||
|
if not token:
|
||||||
|
error("GITHUB_TOKEN не установлен")
|
||||||
|
sys.exit(1)
|
||||||
|
log(f"GITHUB_TOKEN установлен (длина: {len(token)} символов)")
|
||||||
|
return token
|
||||||
|
|
||||||
|
def get_version():
|
||||||
|
"""Получение версии из файла"""
|
||||||
|
version_file = Path(VERSION_FILE)
|
||||||
|
if not version_file.exists():
|
||||||
|
error(f"Файл {VERSION_FILE} не найден")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
version = version_file.read_text().strip()
|
||||||
|
tag = f"lcg.{version}"
|
||||||
|
log(f"Версия: {version}")
|
||||||
|
log(f"Тег: {tag}")
|
||||||
|
return tag
|
||||||
|
|
||||||
|
def check_files():
|
||||||
|
"""Проверка файлов для загрузки"""
|
||||||
|
binaries_path = Path(BINARIES_DIR)
|
||||||
|
if not binaries_path.exists():
|
||||||
|
error(f"Директория {BINARIES_DIR} не найдена")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
files = list(binaries_path.glob("*"))
|
||||||
|
files = [f for f in files if f.is_file()]
|
||||||
|
|
||||||
|
if not files:
|
||||||
|
error(f"В директории {BINARIES_DIR} нет файлов")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
log(f"Найдено файлов: {len(files)}")
|
||||||
|
for file in files:
|
||||||
|
log(f" - {file.name} ({file.stat().st_size} байт)")
|
||||||
|
|
||||||
|
return files
|
||||||
|
|
||||||
|
def create_github_session(token):
|
||||||
|
"""Создание сессии для GitHub API"""
|
||||||
|
session = requests.Session()
|
||||||
|
session.headers.update({
|
||||||
|
'Authorization': f'token {token}',
|
||||||
|
'Accept': 'application/vnd.github.v3+json',
|
||||||
|
'User-Agent': 'release-script'
|
||||||
|
})
|
||||||
|
return session
|
||||||
|
|
||||||
|
def check_existing_release(session, tag):
|
||||||
|
"""Проверка существующего релиза"""
|
||||||
|
log("Проверяем существующий релиз...")
|
||||||
|
url = f"https://api.github.com/repos/{REPO}/releases/tags/{tag}"
|
||||||
|
|
||||||
|
response = session.get(url)
|
||||||
|
if response.status_code == 200:
|
||||||
|
release_data = response.json()
|
||||||
|
log(f"Реліз {tag} уже существует")
|
||||||
|
return release_data
|
||||||
|
elif response.status_code == 404:
|
||||||
|
log(f"Реліз {tag} не найден, создаем новый")
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
error(f"Ошибка проверки релиза: {response.status_code}")
|
||||||
|
debug(f"Ответ: {response.text}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
def create_release(session, tag):
|
||||||
|
"""Создание нового релиза"""
|
||||||
|
log(f"Создаем новый релиз {tag}...")
|
||||||
|
|
||||||
|
data = {
|
||||||
|
"tag_name": tag,
|
||||||
|
"name": tag,
|
||||||
|
"body": f"Release {tag}",
|
||||||
|
"draft": False,
|
||||||
|
"prerelease": False
|
||||||
|
}
|
||||||
|
|
||||||
|
url = f"https://api.github.com/repos/{REPO}/releases"
|
||||||
|
response = session.post(url, json=data)
|
||||||
|
|
||||||
|
if response.status_code == 201:
|
||||||
|
release_data = response.json()
|
||||||
|
log("Реліз создан успешно")
|
||||||
|
return release_data
|
||||||
|
else:
|
||||||
|
error(f"Ошибка создания релиза: {response.status_code}")
|
||||||
|
debug(f"Ответ: {response.text}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
def upload_file(session, upload_url, file_path):
|
||||||
|
"""Загрузка файла в релиз"""
|
||||||
|
filename = file_path.name
|
||||||
|
log(f"Загружаем: {filename}")
|
||||||
|
|
||||||
|
# Убираем {?name,label} из URL
|
||||||
|
upload_url = upload_url.replace("{?name,label}", "")
|
||||||
|
|
||||||
|
with open(file_path, 'rb') as f:
|
||||||
|
headers = {'Content-Type': 'application/octet-stream'}
|
||||||
|
params = {'name': filename}
|
||||||
|
|
||||||
|
response = session.post(
|
||||||
|
upload_url,
|
||||||
|
data=f,
|
||||||
|
headers=headers,
|
||||||
|
params=params
|
||||||
|
)
|
||||||
|
|
||||||
|
if response.status_code == 201:
|
||||||
|
log(f"✓ {filename} загружен")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
error(f"Ошибка загрузки {filename}: {response.status_code}")
|
||||||
|
debug(f"Ответ: {response.text}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Основная функция"""
|
||||||
|
log("=== НАЧАЛО РАБОТЫ СКРИПТА ===")
|
||||||
|
|
||||||
|
# Проверки
|
||||||
|
token = check_environment()
|
||||||
|
tag = get_version()
|
||||||
|
files = check_files()
|
||||||
|
|
||||||
|
# Создание сессии
|
||||||
|
session = create_github_session(token)
|
||||||
|
|
||||||
|
# Проверка/создание релиза
|
||||||
|
release = check_existing_release(session, tag)
|
||||||
|
if not release:
|
||||||
|
release = create_release(session, tag)
|
||||||
|
|
||||||
|
# Получение URL для загрузки
|
||||||
|
upload_url = release['upload_url']
|
||||||
|
log(f"Upload URL: {upload_url}")
|
||||||
|
|
||||||
|
# Загрузка файлов
|
||||||
|
log("=== ЗАГРУЗКА ФАЙЛОВ ===")
|
||||||
|
uploaded = 0
|
||||||
|
failed = 0
|
||||||
|
|
||||||
|
for file_path in files:
|
||||||
|
if upload_file(session, upload_url, file_path):
|
||||||
|
uploaded += 1
|
||||||
|
else:
|
||||||
|
failed += 1
|
||||||
|
|
||||||
|
# Результат
|
||||||
|
log("=== РЕЗУЛЬТАТ ===")
|
||||||
|
log(f"Успешно загружено: {uploaded}")
|
||||||
|
if failed > 0:
|
||||||
|
warn(f"Ошибок: {failed}")
|
||||||
|
else:
|
||||||
|
log("Все файлы загружены успешно!")
|
||||||
|
|
||||||
|
log(f"Реліз доступен: https://github.com/{REPO}/releases/tag/{tag}")
|
||||||
|
log("=== СКРИПТ ЗАВЕРШЕН ===")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
134
shell-code/release.sh
Normal file
134
shell-code/release.sh
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Простой скрипт для создания релиза на GitHub
|
||||||
|
# Использование: GITHUB_TOKEN=your_token ./release.sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Цвета
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
# Функции логирования
|
||||||
|
log() { echo -e "${GREEN}[INFO]${NC} $1"; }
|
||||||
|
error() { echo -e "${RED}[ERROR]${NC} $1" >&2; }
|
||||||
|
warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
|
||||||
|
debug() { echo -e "${BLUE}[DEBUG]${NC} $1"; }
|
||||||
|
|
||||||
|
# Конфигурация
|
||||||
|
REPO="direct-dev-ru/go-lcg"
|
||||||
|
VERSION_FILE="VERSION.txt"
|
||||||
|
BINARIES_DIR="binaries-for-upload"
|
||||||
|
|
||||||
|
# Проверки
|
||||||
|
if [[ -z "$GITHUB_TOKEN" ]]; then
|
||||||
|
error "GITHUB_TOKEN не установлен"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -f "$VERSION_FILE" ]]; then
|
||||||
|
error "Файл $VERSION_FILE не найден"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -d "$BINARIES_DIR" ]]; then
|
||||||
|
error "Директория $BINARIES_DIR не найдена"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Получение версии
|
||||||
|
VERSION=$(cat "$VERSION_FILE" | tr -d ' \t\n\r')
|
||||||
|
TAG="lcg.$VERSION"
|
||||||
|
|
||||||
|
log "Версия: $VERSION"
|
||||||
|
log "Тег: $TAG"
|
||||||
|
|
||||||
|
# Проверяем, существует ли уже релиз
|
||||||
|
log "Проверяем существующий релиз..."
|
||||||
|
EXISTING_RELEASE=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \
|
||||||
|
"https://api.github.com/repos/$REPO/releases/tags/$TAG")
|
||||||
|
|
||||||
|
if echo "$EXISTING_RELEASE" | grep -q '"id":'; then
|
||||||
|
log "Реліз $TAG уже существует, получаем upload_url..."
|
||||||
|
UPLOAD_URL=$(echo "$EXISTING_RELEASE" | grep '"upload_url"' | cut -d'"' -f4 | sed 's/{?name,label}//')
|
||||||
|
else
|
||||||
|
log "Создаем новый релиз $TAG..."
|
||||||
|
|
||||||
|
# Создаем релиз
|
||||||
|
RELEASE_DATA="{\"tag_name\":\"$TAG\",\"name\":\"$TAG\",\"body\":\"Release $TAG\"}"
|
||||||
|
|
||||||
|
RELEASE_RESPONSE=$(curl -s -X POST \
|
||||||
|
-H "Authorization: token $GITHUB_TOKEN" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
"https://api.github.com/repos/$REPO/releases" \
|
||||||
|
-d "$RELEASE_DATA")
|
||||||
|
|
||||||
|
if echo "$RELEASE_RESPONSE" | grep -q '"message"'; then
|
||||||
|
error "Ошибка создания релиза:"
|
||||||
|
echo "$RELEASE_RESPONSE" | grep '"message"' | cut -d'"' -f4
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
UPLOAD_URL=$(echo "$RELEASE_RESPONSE" | grep '"upload_url"' | cut -d'"' -f4 | sed 's/{?name,label}//')
|
||||||
|
log "Реліз создан успешно"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "$UPLOAD_URL" ]]; then
|
||||||
|
error "Не удалось получить upload_url"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "Upload URL: $UPLOAD_URL"
|
||||||
|
|
||||||
|
# Проверяем файлы в директории
|
||||||
|
log "Проверяем файлы в директории $BINARIES_DIR:"
|
||||||
|
ls -la "$BINARIES_DIR"
|
||||||
|
|
||||||
|
# Загружаем файлы
|
||||||
|
log "Загружаем файлы..."
|
||||||
|
UPLOADED=0
|
||||||
|
FAILED=0
|
||||||
|
|
||||||
|
# Простой цикл по всем файлам в директории
|
||||||
|
for file in "$BINARIES_DIR"/*; do
|
||||||
|
if [[ -f "$file" ]]; then
|
||||||
|
filename=$(basename "$file")
|
||||||
|
log "Обрабатываем файл: $file"
|
||||||
|
debug "Имя файла: $filename"
|
||||||
|
|
||||||
|
log "Загружаем: $filename"
|
||||||
|
|
||||||
|
response=$(curl -s -X POST \
|
||||||
|
-H "Authorization: token $GITHUB_TOKEN" \
|
||||||
|
-H "Content-Type: application/octet-stream" \
|
||||||
|
"$UPLOAD_URL?name=$filename" \
|
||||||
|
--data-binary @"$file")
|
||||||
|
|
||||||
|
debug "Ответ API: $response"
|
||||||
|
|
||||||
|
if echo "$response" | grep -q '"message"'; then
|
||||||
|
error "Ошибка загрузки $filename:"
|
||||||
|
echo "$response" | grep '"message"' | cut -d'"' -f4
|
||||||
|
((FAILED++))
|
||||||
|
else
|
||||||
|
log "✓ $filename загружен"
|
||||||
|
((UPLOADED++))
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
warn "Пропускаем не-файл: $file"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Результат
|
||||||
|
log "=== РЕЗУЛЬТАТ ==="
|
||||||
|
log "Успешно загружено: $UPLOADED"
|
||||||
|
if [[ $FAILED -gt 0 ]]; then
|
||||||
|
warn "Ошибок: $FAILED"
|
||||||
|
else
|
||||||
|
log "Все файлы загружены успешно!"
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "Реліз доступен: https://github.com/$REPO/releases/tag/$TAG"
|
||||||
81
shell-code/test_api.py
Normal file
81
shell-code/test_api.py
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Скрипт для тестирования GitHub API
|
||||||
|
Использование: GITHUB_TOKEN=your_token python3 test_api.py
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import requests
|
||||||
|
|
||||||
|
# Цвета
|
||||||
|
class Colors:
|
||||||
|
RED = '\033[0;31m'
|
||||||
|
GREEN = '\033[0;32m'
|
||||||
|
YELLOW = '\033[1;33m'
|
||||||
|
NC = '\033[0m'
|
||||||
|
|
||||||
|
def log(message):
|
||||||
|
print(f"{Colors.GREEN}[INFO]{Colors.NC} {message}")
|
||||||
|
|
||||||
|
def error(message):
|
||||||
|
print(f"{Colors.RED}[ERROR]{Colors.NC} {message}")
|
||||||
|
|
||||||
|
def main():
|
||||||
|
REPO = "direct-dev-ru/go-lcg"
|
||||||
|
|
||||||
|
token = os.getenv('GITHUB_TOKEN')
|
||||||
|
if not token:
|
||||||
|
error("GITHUB_TOKEN не установлен")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
session = requests.Session()
|
||||||
|
session.headers.update({
|
||||||
|
'Authorization': f'token {token}',
|
||||||
|
'Accept': 'application/vnd.github.v3+json'
|
||||||
|
})
|
||||||
|
|
||||||
|
print("=== ТЕСТИРОВАНИЕ GITHUB API ===")
|
||||||
|
|
||||||
|
# Тест 1: Проверка доступа к репозиторию
|
||||||
|
print("1. Проверка доступа к репозиторию...")
|
||||||
|
response = session.get(f"https://api.github.com/repos/{REPO}")
|
||||||
|
|
||||||
|
if response.status_code == 200:
|
||||||
|
repo_data = response.json()
|
||||||
|
print(f"✅ Доступ к репозиторию есть")
|
||||||
|
print(f" Репозиторий: {repo_data['full_name']}")
|
||||||
|
print(f" Описание: {repo_data.get('description', 'Нет описания')}")
|
||||||
|
else:
|
||||||
|
print(f"❌ Ошибка доступа: {response.status_code}")
|
||||||
|
print(f" Ответ: {response.text}")
|
||||||
|
|
||||||
|
# Тест 2: Проверка прав
|
||||||
|
print("\n2. Проверка прав...")
|
||||||
|
if response.status_code == 200:
|
||||||
|
permissions = repo_data.get('permissions', {})
|
||||||
|
if permissions.get('admin'):
|
||||||
|
print("✅ Есть права администратора")
|
||||||
|
elif permissions.get('push'):
|
||||||
|
print("✅ Есть права на запись")
|
||||||
|
else:
|
||||||
|
print("❌ Недостаточно прав для создания релизов")
|
||||||
|
|
||||||
|
# Тест 3: Последние релизы
|
||||||
|
print("\n3. Последние релизы:")
|
||||||
|
releases_response = session.get(f"https://api.github.com/repos/{REPO}/releases")
|
||||||
|
|
||||||
|
if releases_response.status_code == 200:
|
||||||
|
releases = releases_response.json()
|
||||||
|
if releases:
|
||||||
|
for release in releases[:5]:
|
||||||
|
print(f" - {release['tag_name']} ({release['name']})")
|
||||||
|
else:
|
||||||
|
print(" Релизов пока нет")
|
||||||
|
else:
|
||||||
|
print(f" Ошибка получения релизов: {releases_response.status_code}")
|
||||||
|
|
||||||
|
print("\n=== ТЕСТ ЗАВЕРШЕН ===")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Variables
|
|
||||||
VERSION_FILE="VERSION.txt"
|
|
||||||
|
|
||||||
GITHUB_TOKEN="${GITHUB_TOKEN}" # Replace with your GitHub token
|
|
||||||
|
|
||||||
REPO="direct-dev-ru/binaries" # Replace with your GitHub username/repo
|
|
||||||
|
|
||||||
TAG=lcg.$(cat "$VERSION_FILE")
|
|
||||||
|
|
||||||
echo TAG: $TAG
|
|
||||||
|
|
||||||
RELEASE_DIR="/home/su/projects/golang/linux-command-gpt/binaries-for-upload"
|
|
||||||
|
|
||||||
body="{\"tag_name\":\"${TAG}\", \"target_commitish\":\"main\", \"name\":\"${TAG}\", \
|
|
||||||
\"body\":\"${TAG}\", \"draft\":false, \"prerelease\":false, \"generate_release_notes\":false}"
|
|
||||||
|
|
||||||
echo BODY: $body
|
|
||||||
|
|
||||||
response=$(curl -L -X POST \
|
|
||||||
-H "Accept: application/vnd.github+json" \
|
|
||||||
-H "Authorization: Bearer ${GITHUB_TOKEN}" \
|
|
||||||
-H "X-GitHub-Api-Version: 2022-11-28" \
|
|
||||||
https://api.github.com/repos/direct-dev-ru/binaries/releases \
|
|
||||||
-d $body)
|
|
||||||
|
|
||||||
echo $response
|
|
||||||
|
|
||||||
# Extract the upload URL from the response
|
|
||||||
upload_url=$(echo "$response" | jq -r '.upload_url' | sed "s/{?name,label}//")
|
|
||||||
|
|
||||||
# Check if the release was created successfully
|
|
||||||
if [[ "$response" == *"Not Found"* ]]; then
|
|
||||||
echo "Error: Repository not found or invalid token."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Upload each binary file
|
|
||||||
for file in "$RELEASE_DIR"/*; do
|
|
||||||
if [[ -f "$file" ]]; then
|
|
||||||
filename=$(basename "$file")
|
|
||||||
echo "Uploading $filename..."
|
|
||||||
response=$(curl -s -X POST -H "Authorization: token $GITHUB_TOKEN" \
|
|
||||||
-H "Content-Type: application/octet-stream" \
|
|
||||||
"$upload_url?name=$filename" \
|
|
||||||
--data-binary @"$file")
|
|
||||||
echo $response
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "All binaries uploaded successfully."
|
|
||||||
Reference in New Issue
Block a user