Функция: Добавлен рабочий процесс GitHub Actions для синхронизации вики
Синхронизация Wiki / Синхронизация Wiki (push) Successful in 2s
Синхронизация Wiki / Синхронизация Wiki (push) Successful in 2s
- Реализован новый рабочий процесс в `.github/workflows/wiki-sync.yml` для синхронизации вики с основным репозиторием при отправке изменений в ветку master. - Рабочий процесс включает шаги клонирования репозитория, проверки наличия папки wiki и синхронизации содержимого вики с вики DFGit. Документация: Создание описания секретов для развертывания и конфигурации - Добавлен файл `secrets_description.md`, подробно описывающий необходимые секреты для развертывания и настройки проекта `configure_nginx_manager`. Документация: Добавление документации по сборке и релизам - Создан файл `Build_and_Release.md`, описывающий процесс сборки с использованием PyInstaller и этапы упаковки релиза. Документация: Введение журнала изменений для отслеживания версий - Добавлен файл `Changelog.md` для краткого описания основных версий и изменений, внесенных в проект. Документация: Документирование команд и скриптов, доступных в проекте - Создан файл `Commands.md` для перечисления команд CLI и команд Makefile для удобства пользователей. Документация: Предоставление подробной информации о конфигурации проекта - Добавлен файл `Configuration.md` для объяснения структуры конфигурации JSON и параметров. Документация: Описание действий развертывания и необходимых секретов - Создан файл `Deploy_Actions_Secrets.md` для описания секретов, необходимых для развертывания через GitHub Actions. Документация: Объяснение методов синхронизации Gitea с GitHub - Добавлен файл `Gitea_Sync.md` для описания различных методов синхронизации репозиториев из Gitea в GitHub. Документация: Создание домашней страницы для вики проекта - Создан файл `Home.md`, который служит основной точкой входа для вики проекта. Документация: Описание процедур установки проекта - Добавлен файл `Installation.md` с подробным описанием методов и требований к установке. Документация: Описание рабочего процесса Let's Encrypt для управления сертификатами - Создан файл `LetsEncrypt_Workflow.md` для объяснения процесса получения и обновления SSL-сертификатов. Документация: Интеграция с документацией Nginx Proxy Manager - Добавлен файл `Nginx_Proxy_Manager.md` для объяснения синхронизации сертификатов с NPM. Документация: Определение структуры проекта для лучшего понимания - Создан файл `Project_Structure.md` для описания ключевых файлов и скриптов проекта. Документация: Устранение распространенных проблем с API reg.ru - Добавлен файл `RegRu_API_Troubleshooting.md` для помощи пользователям в диагностике и устранении проблем, связанных с API. Документация: Предоставить рекомендации по тестированию проекта - Создан файл `Testing.md`, описывающий стратегии тестирования и ограничения, связанные с Let's Encrypt. Документация: Добавить боковую панель навигации для вики - Создан файл `_Sidebar.md` для упрощения навигации по страницам вики.
This commit is contained in:
@@ -1,330 +0,0 @@
|
||||
# Настройка Gitea Actions для автоматической сборки
|
||||
|
||||
## 📋 Предварительные требования
|
||||
|
||||
### 1. Gitea с поддержкой Actions
|
||||
|
||||
Убедитесь, что ваш Gitea имеет включенные Actions:
|
||||
|
||||
```ini
|
||||
# В app.ini Gitea
|
||||
[actions]
|
||||
ENABLED = true
|
||||
DEFAULT_ACTIONS_URL = https://gitea.com
|
||||
```
|
||||
|
||||
### 2. Gitea Runner
|
||||
|
||||
Установите и настройте Gitea Act Runner:
|
||||
|
||||
```bash
|
||||
# Скачать runner
|
||||
wget https://dl.gitea.com/act_runner/latest/act_runner-linux-amd64 -O act_runner
|
||||
chmod +x act_runner
|
||||
|
||||
# Зарегистрировать runner
|
||||
./act_runner register --no-interactive \
|
||||
--instance https://your-gitea-instance.com \
|
||||
--token YOUR_RUNNER_TOKEN \
|
||||
--name my-runner
|
||||
|
||||
# Запустить runner
|
||||
./act_runner daemon
|
||||
```
|
||||
|
||||
Или через Docker:
|
||||
|
||||
```bash
|
||||
docker run -d \
|
||||
--name gitea-runner \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
-v $PWD/runner-data:/data \
|
||||
-e GITEA_INSTANCE_URL=https://your-gitea-instance.com \
|
||||
-e GITEA_RUNNER_REGISTRATION_TOKEN=YOUR_TOKEN \
|
||||
gitea/act_runner:latest
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Использование
|
||||
|
||||
### Создание релиза автоматически
|
||||
|
||||
1. **Создайте и отправьте тег:**
|
||||
|
||||
```bash
|
||||
# Создать тег
|
||||
git tag -a v1.0.0 -m "Release version 1.0.0"
|
||||
|
||||
# Отправить тег на сервер
|
||||
git push origin v1.0.0
|
||||
```
|
||||
|
||||
2. **Gitea автоматически:**
|
||||
- Запустит workflow `.gitea/workflows/release.yml`
|
||||
- Соберет Linux версию на Ubuntu runner
|
||||
- Соберет Windows версию на Windows runner
|
||||
- Создаст релиз с артефактами
|
||||
- Добавит контрольные суммы SHA256 и MD5
|
||||
|
||||
### Ручной запуск workflow
|
||||
|
||||
В веб-интерфейсе Gitea:
|
||||
|
||||
1. Перейдите в **Repository → Actions**
|
||||
2. Выберите workflow **Build and Release**
|
||||
3. Нажмите **Run workflow**
|
||||
4. Укажите версию (опционально)
|
||||
|
||||
---
|
||||
|
||||
## 📂 Структура workflows
|
||||
|
||||
```
|
||||
.gitea/
|
||||
└── workflows/
|
||||
├── build-release.yml # Простой workflow (совместим с GitHub)
|
||||
└── release.yml # Расширенный workflow с уведомлениями
|
||||
```
|
||||
|
||||
### build-release.yml
|
||||
|
||||
Базовый workflow, совместимый с GitHub Actions:
|
||||
- Сборка для Linux и Windows
|
||||
- Создание пакетов
|
||||
- Генерация контрольных сумм
|
||||
- Создание релиза
|
||||
|
||||
**Использование:**
|
||||
```bash
|
||||
git tag v1.0.0
|
||||
git push origin v1.0.0
|
||||
```
|
||||
|
||||
### release.yml
|
||||
|
||||
Расширенный workflow с дополнительными возможностями:
|
||||
- Детальные release notes
|
||||
- MD5 + SHA256 checksums
|
||||
- Уведомления после релиза
|
||||
- Поддержка ручного запуска
|
||||
|
||||
**Использование:**
|
||||
```bash
|
||||
# Автоматически при теге
|
||||
git tag v1.0.0
|
||||
git push origin v1.0.0
|
||||
|
||||
# Или вручную через веб-интерфейс
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Настройка
|
||||
|
||||
### Переменные окружения
|
||||
|
||||
Workflow использует следующие переменные:
|
||||
|
||||
| Переменная | Описание | Где установить |
|
||||
|------------|----------|----------------|
|
||||
| `GITEA_TOKEN` | Токен для создания релиза | Repository Secrets |
|
||||
| `GITHUB_TOKEN` | Автоматически (fallback) | Встроенный |
|
||||
|
||||
### Создание GITEA_TOKEN
|
||||
|
||||
1. В Gitea: **Settings → Applications → Generate New Token**
|
||||
2. Выберите права: `repo`, `write:packages`
|
||||
3. Скопируйте токен
|
||||
4. В репозитории: **Settings → Secrets → Add Secret**
|
||||
- Name: `GITEA_TOKEN`
|
||||
- Value: ваш токен
|
||||
|
||||
---
|
||||
|
||||
## 📦 Артефакты релиза
|
||||
|
||||
После успешной сборки в релизе будут доступны:
|
||||
|
||||
```
|
||||
letsencrypt-regru-linux-x86_64.tar.gz
|
||||
letsencrypt-regru-linux-x86_64.tar.gz.sha256
|
||||
letsencrypt-regru-linux-x86_64.tar.gz.md5
|
||||
letsencrypt-regru-windows-x86_64.zip
|
||||
letsencrypt-regru-windows-x86_64.zip.sha256
|
||||
letsencrypt-regru-windows-x86_64.zip.md5
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🐛 Troubleshooting
|
||||
|
||||
### Workflow не запускается
|
||||
|
||||
**Проблема:** После push тега workflow не запускается
|
||||
|
||||
**Решение:**
|
||||
1. Проверьте, что Actions включены в настройках репозитория
|
||||
2. Проверьте `.gitea/workflows/*.yml` на синтаксические ошибки
|
||||
3. Убедитесь, что runner зарегистрирован и запущен
|
||||
|
||||
```bash
|
||||
# Проверить статус runner
|
||||
./act_runner status
|
||||
|
||||
# Посмотреть логи runner
|
||||
./act_runner daemon --debug
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Ошибка при сборке Windows
|
||||
|
||||
**Проблема:** `make: command not found` на Windows
|
||||
|
||||
**Решение:**
|
||||
|
||||
Установите Make для Windows или используйте альтернативный workflow:
|
||||
|
||||
```yaml
|
||||
- name: Build Windows executable (без make)
|
||||
run: |
|
||||
pyinstaller --onefile --name letsencrypt-regru letsencrypt_regru_api.py
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Релиз создается без файлов
|
||||
|
||||
**Проблема:** Релиз создан, но артефакты отсутствуют
|
||||
|
||||
**Решение:**
|
||||
|
||||
Проверьте логи job `create-release`:
|
||||
|
||||
1. Перейдите в **Actions → Build and Release → create-release**
|
||||
2. Проверьте шаг "Download artifacts"
|
||||
3. Убедитесь, что предыдущие jobs (`build-linux`, `build-windows`) завершились успешно
|
||||
|
||||
---
|
||||
|
||||
### Permission denied при создании релиза
|
||||
|
||||
**Проблема:** `Error: Resource not accessible by integration`
|
||||
|
||||
**Решение:**
|
||||
|
||||
1. Проверьте права токена:
|
||||
- `GITEA_TOKEN` должен иметь права `repo` и `write:packages`
|
||||
|
||||
2. Или используйте встроенный `GITHUB_TOKEN`:
|
||||
- Убедитесь, что в настройках репозитория включены Actions
|
||||
|
||||
---
|
||||
|
||||
## 📊 Мониторинг сборок
|
||||
|
||||
### Просмотр логов
|
||||
|
||||
1. **Web UI:**
|
||||
- Repository → Actions
|
||||
- Выберите workflow run
|
||||
- Кликните на job для просмотра логов
|
||||
|
||||
2. **API:**
|
||||
```bash
|
||||
curl -H "Authorization: token YOUR_TOKEN" \
|
||||
https://your-gitea.com/api/v1/repos/USER/REPO/actions/runs
|
||||
```
|
||||
|
||||
### Статус badges
|
||||
|
||||
Добавьте в README.md:
|
||||
|
||||
```markdown
|
||||
[](https://your-gitea.com/USER/REPO/actions)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Автоматизация релизов
|
||||
|
||||
### Semantic Versioning
|
||||
|
||||
Используйте теги с семантическим версионированием:
|
||||
|
||||
```bash
|
||||
# Major release (несовместимые изменения)
|
||||
git tag v2.0.0
|
||||
|
||||
# Minor release (новые функции)
|
||||
git tag v1.1.0
|
||||
|
||||
# Patch release (исправления)
|
||||
git tag v1.0.1
|
||||
```
|
||||
|
||||
### Pre-release
|
||||
|
||||
Для тестовых релизов используйте suffix:
|
||||
|
||||
```bash
|
||||
git tag v1.0.0-beta.1
|
||||
git tag v1.0.0-rc.1
|
||||
```
|
||||
|
||||
В workflow автоматически будет установлен `prerelease: true` для таких тегов.
|
||||
|
||||
---
|
||||
|
||||
## 📝 Changelog автоматизация
|
||||
|
||||
### Использование conventional commits
|
||||
|
||||
```bash
|
||||
git commit -m "feat: добавлена поддержка wildcard сертификатов"
|
||||
git commit -m "fix: исправлена ошибка загрузки в NPM"
|
||||
git commit -m "docs: обновлена документация"
|
||||
```
|
||||
|
||||
### Генерация CHANGELOG.md
|
||||
|
||||
Добавьте в workflow:
|
||||
|
||||
```yaml
|
||||
- name: Generate Changelog
|
||||
run: |
|
||||
git log $(git describe --tags --abbrev=0)..HEAD --pretty=format:"- %s" > CHANGELOG.md
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Рекомендации
|
||||
|
||||
1. **Используйте теги только для стабильных релизов**
|
||||
- Тестируйте перед созданием тега
|
||||
- Проверяйте сборку локально: `make release`
|
||||
|
||||
2. **Проверяйте контрольные суммы**
|
||||
- Всегда включайте SHA256 и MD5
|
||||
- Документируйте процесс проверки для пользователей
|
||||
|
||||
3. **Версионирование**
|
||||
- Следуйте семантическому версионированию
|
||||
- Документируйте breaking changes
|
||||
|
||||
4. **Тестирование**
|
||||
- Запускайте workflow вручную перед тегированием
|
||||
- Проверяйте артефакты после сборки
|
||||
|
||||
---
|
||||
|
||||
## 🔗 Полезные ссылки
|
||||
|
||||
- [Gitea Actions Documentation](https://docs.gitea.com/next/usage/actions/overview)
|
||||
- [Act Runner GitHub](https://github.com/nektos/act)
|
||||
- [Workflow Syntax](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions)
|
||||
|
||||
---
|
||||
|
||||
**Примечание:** Эти workflows совместимы с GitHub Actions и могут использоваться на обеих платформах.
|
||||
@@ -1,211 +0,0 @@
|
||||
name: Build Releases
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*' # Срабатывает на теги вида v1.0, v2.0.1 и т.д.
|
||||
workflow_dispatch: # Возможность запустить вручную
|
||||
|
||||
jobs:
|
||||
build-linux:
|
||||
name: Build Linux Executable
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.9'
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install pyinstaller
|
||||
pip install -r requirements.txt
|
||||
|
||||
- name: Build Linux executable
|
||||
run: |
|
||||
make build-linux
|
||||
|
||||
- name: Test Linux executable
|
||||
run: |
|
||||
chmod +x dist/letsencrypt-regru
|
||||
dist/letsencrypt-regru --help
|
||||
|
||||
- name: Create Linux package
|
||||
run: |
|
||||
make package-linux
|
||||
|
||||
- name: Upload Linux artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: linux-executable
|
||||
path: dist/letsencrypt-regru-linux-x86_64.tar.gz
|
||||
|
||||
- name: Generate SHA256 checksum
|
||||
run: |
|
||||
cd dist
|
||||
sha256sum letsencrypt-regru-linux-x86_64.tar.gz > letsencrypt-regru-linux-x86_64.tar.gz.sha256
|
||||
|
||||
- name: Upload checksum
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: linux-checksum
|
||||
path: dist/letsencrypt-regru-linux-x86_64.tar.gz.sha256
|
||||
|
||||
build-windows:
|
||||
name: Build Windows Executable
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.9'
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install pyinstaller
|
||||
pip install -r requirements.txt
|
||||
|
||||
- name: Build Windows executable
|
||||
run: |
|
||||
make build-windows
|
||||
|
||||
- name: Test Windows executable
|
||||
run: |
|
||||
dist\letsencrypt-regru.exe --help
|
||||
|
||||
- name: Create Windows package
|
||||
run: |
|
||||
make package-windows
|
||||
|
||||
- name: Upload Windows artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: windows-executable
|
||||
path: dist/letsencrypt-regru-windows-x86_64.zip
|
||||
|
||||
- name: Generate SHA256 checksum
|
||||
run: |
|
||||
cd dist
|
||||
certutil -hashfile letsencrypt-regru-windows-x86_64.zip SHA256 > letsencrypt-regru-windows-x86_64.zip.sha256
|
||||
|
||||
- name: Upload checksum
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: windows-checksum
|
||||
path: dist/letsencrypt-regru-windows-x86_64.zip.sha256
|
||||
|
||||
create-release:
|
||||
name: Create Gitea Release
|
||||
needs: [build-linux, build-windows]
|
||||
runs-on: ubuntu-latest
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Download Linux artifact
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: linux-executable
|
||||
path: ./artifacts
|
||||
|
||||
- name: Download Linux checksum
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: linux-checksum
|
||||
path: ./artifacts
|
||||
|
||||
- name: Download Windows artifact
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: windows-executable
|
||||
path: ./artifacts
|
||||
|
||||
- name: Download Windows checksum
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: windows-checksum
|
||||
path: ./artifacts
|
||||
|
||||
- name: Get tag name
|
||||
id: get_version
|
||||
run: echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Create Release
|
||||
uses: actions/gitea-release@v1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
tag_name: ${{ steps.get_version.outputs.VERSION }}
|
||||
name: Let's Encrypt RegRu Manager ${{ steps.get_version.outputs.VERSION }}
|
||||
body: |
|
||||
## Let's Encrypt RegRu Manager ${{ steps.get_version.outputs.VERSION }}
|
||||
|
||||
### 📦 Релизные пакеты
|
||||
|
||||
**Linux (Ubuntu/Debian/CentOS):**
|
||||
- `letsencrypt-regru-linux-x86_64.tar.gz` - Исполняемый файл + файлы
|
||||
- `letsencrypt-regru-linux-x86_64.tar.gz.sha256` - Контрольная сумма
|
||||
|
||||
**Windows:**
|
||||
- `letsencrypt-regru-windows-x86_64.zip` - Исполняемый файл + файлы
|
||||
- `letsencrypt-regru-windows-x86_64.zip.sha256` - Контрольная сумма
|
||||
|
||||
### 🚀 Быстрая установка
|
||||
|
||||
**Linux:**
|
||||
```bash
|
||||
wget https://your-gitea-instance.com/${{ github.repository }}/releases/download/${{ steps.get_version.outputs.VERSION }}/letsencrypt-regru-linux-x86_64.tar.gz
|
||||
tar -xzf letsencrypt-regru-linux-x86_64.tar.gz
|
||||
sudo mv letsencrypt-regru /usr/local/bin/
|
||||
sudo chmod +x /usr/local/bin/letsencrypt-regru
|
||||
```
|
||||
|
||||
**Windows:**
|
||||
Скачайте `letsencrypt-regru-windows-x86_64.zip` и распакуйте.
|
||||
|
||||
### 📖 Документация
|
||||
|
||||
- [README.md](README.md)
|
||||
- [BUILD_GUIDE.md](BUILD_GUIDE.md)
|
||||
- [INSTALL_GUIDE.md](docs/INSTALL_GUIDE.md)
|
||||
|
||||
### ⚠️ Важно
|
||||
|
||||
- Исполняемые файлы требуют установленного `certbot` в системе
|
||||
- Linux версия требует права root (sudo)
|
||||
- Windows версия не поддерживает certbot напрямую (используйте WSL)
|
||||
|
||||
### 🔐 Проверка контрольных сумм
|
||||
|
||||
**Linux:**
|
||||
```bash
|
||||
sha256sum -c letsencrypt-regru-linux-x86_64.tar.gz.sha256
|
||||
```
|
||||
|
||||
**Windows:**
|
||||
```powershell
|
||||
certutil -hashfile letsencrypt-regru-windows-x86_64.zip SHA256
|
||||
```
|
||||
|
||||
### 📝 Changelog
|
||||
|
||||
- Автоматическая сборка релиза ${{ steps.get_version.outputs.VERSION }}
|
||||
- См. коммиты для деталей изменений
|
||||
files: |
|
||||
./artifacts/letsencrypt-regru-linux-x86_64.tar.gz
|
||||
./artifacts/letsencrypt-regru-linux-x86_64.tar.gz.sha256
|
||||
./artifacts/letsencrypt-regru-windows-x86_64.zip
|
||||
./artifacts/letsencrypt-regru-windows-x86_64.zip.sha256
|
||||
draft: false
|
||||
prerelease: false
|
||||
@@ -1,387 +0,0 @@
|
||||
name: Build and Release (Gitea Native)
|
||||
|
||||
# Этот workflow оптимизирован для Gitea
|
||||
# Использует нативные возможности Gitea Actions
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
- 'release-*'
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: 'Version tag (e.g., v1.0.0)'
|
||||
required: false
|
||||
default: 'dev'
|
||||
|
||||
env:
|
||||
APP_NAME: letsencrypt-regru
|
||||
PYTHON_VERSION: '3.9'
|
||||
|
||||
jobs:
|
||||
# ============================================================================
|
||||
# Сборка для Linux
|
||||
# ============================================================================
|
||||
build-linux:
|
||||
name: 🐧 Build Linux
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: 📥 Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: 🐍 Set up Python ${{ env.PYTHON_VERSION }}
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ env.PYTHON_VERSION }}
|
||||
cache: 'pip'
|
||||
|
||||
- name: 📦 Install system dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y build-essential
|
||||
|
||||
- name: 📚 Install Python dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip setuptools wheel
|
||||
pip install pyinstaller
|
||||
if [ -f requirements.txt ]; then
|
||||
pip install -r requirements.txt
|
||||
else
|
||||
pip install requests certbot cryptography
|
||||
fi
|
||||
|
||||
- name: ℹ️ Build info
|
||||
run: |
|
||||
make build-info
|
||||
|
||||
- name: 🔨 Build Linux executable
|
||||
run: |
|
||||
make build-linux
|
||||
|
||||
- name: ✅ Test executable
|
||||
run: |
|
||||
chmod +x dist/${{ env.APP_NAME }}
|
||||
./dist/${{ env.APP_NAME }} --help
|
||||
./dist/${{ env.APP_NAME }} --create-config /tmp/test_config.json
|
||||
|
||||
- name: 📦 Create distribution package
|
||||
run: |
|
||||
make package-linux
|
||||
|
||||
- name: 🔐 Generate checksums
|
||||
run: |
|
||||
cd dist
|
||||
sha256sum ${{ env.APP_NAME }}-linux-x86_64.tar.gz > ${{ env.APP_NAME }}-linux-x86_64.tar.gz.sha256
|
||||
md5sum ${{ env.APP_NAME }}-linux-x86_64.tar.gz > ${{ env.APP_NAME }}-linux-x86_64.tar.gz.md5
|
||||
cat ${{ env.APP_NAME }}-linux-x86_64.tar.gz.sha256
|
||||
|
||||
- name: 📤 Upload Linux package
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: linux-package
|
||||
path: |
|
||||
dist/${{ env.APP_NAME }}-linux-x86_64.tar.gz
|
||||
dist/${{ env.APP_NAME }}-linux-x86_64.tar.gz.sha256
|
||||
dist/${{ env.APP_NAME }}-linux-x86_64.tar.gz.md5
|
||||
retention-days: 7
|
||||
|
||||
# ============================================================================
|
||||
# Сборка для Windows
|
||||
# ============================================================================
|
||||
build-windows:
|
||||
name: 🪟 Build Windows
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
- name: 📥 Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: 🐍 Set up Python ${{ env.PYTHON_VERSION }}
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ env.PYTHON_VERSION }}
|
||||
cache: 'pip'
|
||||
|
||||
- name: 📚 Install Python dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip setuptools wheel
|
||||
pip install pyinstaller
|
||||
if (Test-Path requirements.txt) {
|
||||
pip install -r requirements.txt
|
||||
} else {
|
||||
pip install requests certbot cryptography
|
||||
}
|
||||
|
||||
- name: 🔨 Build Windows executable
|
||||
run: |
|
||||
make build-windows
|
||||
|
||||
- name: ✅ Test executable
|
||||
run: |
|
||||
dist\${{ env.APP_NAME }}.exe --help
|
||||
dist\${{ env.APP_NAME }}.exe --create-config test_config.json
|
||||
|
||||
- name: 📦 Create distribution package
|
||||
run: |
|
||||
make package-windows
|
||||
|
||||
- name: 🔐 Generate checksums
|
||||
run: |
|
||||
cd dist
|
||||
certutil -hashfile ${{ env.APP_NAME }}-windows-x86_64.zip SHA256 > ${{ env.APP_NAME }}-windows-x86_64.zip.sha256
|
||||
certutil -hashfile ${{ env.APP_NAME }}-windows-x86_64.zip MD5 > ${{ env.APP_NAME }}-windows-x86_64.zip.md5
|
||||
type ${{ env.APP_NAME }}-windows-x86_64.zip.sha256
|
||||
|
||||
- name: 📤 Upload Windows package
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: windows-package
|
||||
path: |
|
||||
dist/${{ env.APP_NAME }}-windows-x86_64.zip
|
||||
dist/${{ env.APP_NAME }}-windows-x86_64.zip.sha256
|
||||
dist/${{ env.APP_NAME }}-windows-x86_64.zip.md5
|
||||
retention-days: 7
|
||||
|
||||
# ============================================================================
|
||||
# Создание релиза в Gitea
|
||||
# ============================================================================
|
||||
create-release:
|
||||
name: 📦 Create Release
|
||||
needs: [build-linux, build-windows]
|
||||
runs-on: ubuntu-latest
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
|
||||
steps:
|
||||
- name: 📥 Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: 📥 Download Linux artifacts
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: linux-package
|
||||
path: ./release
|
||||
|
||||
- name: 📥 Download Windows artifacts
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: windows-package
|
||||
path: ./release
|
||||
|
||||
- name: 📋 List release files
|
||||
run: |
|
||||
echo "Release files:"
|
||||
ls -lh ./release/
|
||||
|
||||
- name: 🏷️ Get version info
|
||||
id: version
|
||||
run: |
|
||||
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
||||
VERSION="${{ github.event.inputs.version }}"
|
||||
else
|
||||
VERSION="${GITHUB_REF#refs/tags/}"
|
||||
fi
|
||||
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
|
||||
echo "Release version: $VERSION"
|
||||
|
||||
- name: 📝 Generate release notes
|
||||
id: release_notes
|
||||
run: |
|
||||
cat > release_notes.md << 'EOF'
|
||||
## 🎉 Let's Encrypt RegRu Manager ${{ steps.version.outputs.VERSION }}
|
||||
|
||||
Автоматическое управление SSL сертификатами Let's Encrypt для доменов на reg.ru с интеграцией в Nginx Proxy Manager.
|
||||
|
||||
### 📦 Файлы релиза
|
||||
|
||||
#### Linux (Ubuntu 20.04+, Debian 10+, CentOS 8+)
|
||||
- **letsencrypt-regru-linux-x86_64.tar.gz** - Исполняемый файл (ELF 64-bit)
|
||||
- **letsencrypt-regru-linux-x86_64.tar.gz.sha256** - SHA256 контрольная сумма
|
||||
- **letsencrypt-regru-linux-x86_64.tar.gz.md5** - MD5 контрольная сумма
|
||||
|
||||
#### Windows (10/11, Server 2019+)
|
||||
- **letsencrypt-regru-windows-x86_64.zip** - Исполняемый файл (PE32+)
|
||||
- **letsencrypt-regru-windows-x86_64.zip.sha256** - SHA256 контрольная сумма
|
||||
- **letsencrypt-regru-windows-x86_64.zip.md5** - MD5 контрольная сумма
|
||||
|
||||
---
|
||||
|
||||
### 🚀 Быстрая установка
|
||||
|
||||
#### Linux (одна команда):
|
||||
```bash
|
||||
curl -fsSL https://your-gitea.com/api/v1/repos/${{ github.repository }}/releases/tags/${{ steps.version.outputs.VERSION }} | \
|
||||
jq -r '.assets[] | select(.name | contains("linux")) | .browser_download_url' | \
|
||||
xargs wget -O letsencrypt-regru.tar.gz && \
|
||||
tar -xzf letsencrypt-regru.tar.gz && \
|
||||
sudo mv letsencrypt-regru /usr/local/bin/ && \
|
||||
sudo chmod +x /usr/local/bin/letsencrypt-regru
|
||||
```
|
||||
|
||||
#### Или вручную:
|
||||
```bash
|
||||
# 1. Скачать
|
||||
wget https://your-gitea.com/${{ github.repository }}/releases/download/${{ steps.version.outputs.VERSION }}/letsencrypt-regru-linux-x86_64.tar.gz
|
||||
|
||||
# 2. Проверить контрольную сумму
|
||||
wget https://your-gitea.com/${{ github.repository }}/releases/download/${{ steps.version.outputs.VERSION }}/letsencrypt-regru-linux-x86_64.tar.gz.sha256
|
||||
sha256sum -c letsencrypt-regru-linux-x86_64.tar.gz.sha256
|
||||
|
||||
# 3. Распаковать и установить
|
||||
tar -xzf letsencrypt-regru-linux-x86_64.tar.gz
|
||||
sudo mv letsencrypt-regru /usr/local/bin/
|
||||
sudo chmod +x /usr/local/bin/letsencrypt-regru
|
||||
|
||||
# 4. Проверить
|
||||
letsencrypt-regru --help
|
||||
```
|
||||
|
||||
#### Windows:
|
||||
```powershell
|
||||
# Скачать и распаковать
|
||||
Invoke-WebRequest -Uri "https://your-gitea.com/${{ github.repository }}/releases/download/${{ steps.version.outputs.VERSION }}/letsencrypt-regru-windows-x86_64.zip" -OutFile "letsencrypt-regru.zip"
|
||||
Expand-Archive -Path letsencrypt-regru.zip -DestinationPath "C:\Program Files\LetsEncrypt-RegRu"
|
||||
|
||||
# Проверить
|
||||
& "C:\Program Files\LetsEncrypt-RegRu\letsencrypt-regru.exe" --help
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### ✨ Основные возможности
|
||||
|
||||
- ✅ Автоматическое получение Let's Encrypt сертификатов
|
||||
- ✅ DNS-валидация через API reg.ru
|
||||
- ✅ Поддержка wildcard сертификатов (*.domain.com)
|
||||
- ✅ Автоматическая загрузка в Nginx Proxy Manager
|
||||
- ✅ Автоматическое обновление сертификатов
|
||||
- ✅ Systemd интеграция для автоматизации
|
||||
- ✅ Подробное логирование
|
||||
- ✅ Генерация тестовых самоподписанных сертификатов
|
||||
|
||||
---
|
||||
|
||||
### 📋 Системные требования
|
||||
|
||||
#### Linux:
|
||||
- Ubuntu 20.04+ / Debian 10+ / CentOS 8+ / RHEL 8+
|
||||
- certbot (устанавливается автоматически через `letsencrypt_regru.sh`)
|
||||
- 50 MB свободного места
|
||||
- Права root (sudo)
|
||||
|
||||
#### Windows:
|
||||
- Windows 10/11 или Server 2019+
|
||||
- **Важно:** certbot не поддерживается напрямую на Windows
|
||||
- Рекомендуется использовать WSL (Windows Subsystem for Linux)
|
||||
|
||||
---
|
||||
|
||||
### 📖 Документация
|
||||
|
||||
- **[README.md](README.md)** - Полное руководство пользователя
|
||||
- **[BUILD_GUIDE.md](BUILD_GUIDE.md)** - Руководство по сборке из исходников
|
||||
- **[INSTALL_GUIDE.md](docs/INSTALL_GUIDE.md)** - Детальная инструкция по установке
|
||||
- **[MAKEFILE_COMMANDS.md](MAKEFILE_COMMANDS.md)** - Справка по командам Makefile
|
||||
|
||||
---
|
||||
|
||||
### ⚠️ Важная информация
|
||||
|
||||
1. **Certbot зависимость:**
|
||||
- Исполняемый файл НЕ включает certbot
|
||||
- certbot должен быть установлен в системе
|
||||
- Используется через subprocess
|
||||
|
||||
2. **Размер файла:**
|
||||
- Linux: ~45-55 MB (включая Python runtime)
|
||||
- Windows: ~40-50 MB (включая Python runtime)
|
||||
|
||||
3. **Первый запуск:**
|
||||
- Может занять 5-10 секунд (распаковка)
|
||||
- Последующие запуски быстрее (~1-2 сек)
|
||||
|
||||
4. **Безопасность:**
|
||||
- Файлы подписаны контрольными суммами SHA256 и MD5
|
||||
- Всегда проверяйте контрольные суммы перед использованием
|
||||
|
||||
---
|
||||
|
||||
### 🔐 Проверка контрольных сумм
|
||||
|
||||
#### Linux:
|
||||
```bash
|
||||
# SHA256
|
||||
sha256sum -c letsencrypt-regru-linux-x86_64.tar.gz.sha256
|
||||
|
||||
# MD5
|
||||
md5sum -c letsencrypt-regru-linux-x86_64.tar.gz.md5
|
||||
```
|
||||
|
||||
#### Windows:
|
||||
```powershell
|
||||
# SHA256
|
||||
certutil -hashfile letsencrypt-regru-windows-x86_64.zip SHA256
|
||||
|
||||
# MD5
|
||||
certutil -hashfile letsencrypt-regru-windows-x86_64.zip MD5
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 🐛 Проблемы и поддержка
|
||||
|
||||
Если у вас возникли проблемы:
|
||||
|
||||
1. Проверьте [Issues](../../issues)
|
||||
2. Создайте новый [Issue](../../issues/new)
|
||||
3. См. раздел [Troubleshooting](BUILD_GUIDE.md#troubleshooting) в BUILD_GUIDE.md
|
||||
|
||||
---
|
||||
|
||||
### 📝 Changelog
|
||||
|
||||
См. [коммиты](${{ github.server_url }}/${{ github.repository }}/commits/${{ steps.version.outputs.VERSION }}) для деталей изменений.
|
||||
|
||||
---
|
||||
|
||||
**Автор:** Фофанов Дмитрий
|
||||
**Дата релиза:** $(date -u +"%Y-%m-%d %H:%M:%S UTC")
|
||||
**Версия:** ${{ steps.version.outputs.VERSION }}
|
||||
EOF
|
||||
|
||||
cat release_notes.md
|
||||
|
||||
- name: 🚀 Create Gitea Release
|
||||
uses: actions/gitea-release@v1
|
||||
env:
|
||||
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
files: |
|
||||
release/*
|
||||
tag_name: ${{ steps.version.outputs.VERSION }}
|
||||
name: "Let's Encrypt RegRu Manager ${{ steps.version.outputs.VERSION }}"
|
||||
body_path: release_notes.md
|
||||
draft: false
|
||||
prerelease: false
|
||||
|
||||
# ============================================================================
|
||||
# Уведомление о релизе (опционально)
|
||||
# ============================================================================
|
||||
notify:
|
||||
name: 📢 Notify
|
||||
needs: [create-release]
|
||||
runs-on: ubuntu-latest
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
|
||||
steps:
|
||||
- name: 📧 Send notification
|
||||
run: |
|
||||
echo "Release created successfully!"
|
||||
echo "Tag: ${{ github.ref_name }}"
|
||||
echo "Repository: ${{ github.repository }}"
|
||||
# Здесь можно добавить отправку уведомлений через webhook, email и т.д.
|
||||
@@ -1,201 +0,0 @@
|
||||
name: Build Releases
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*' # Срабатывает на теги вида v1.0, v2.0.1 и т.д.
|
||||
workflow_dispatch: # Возможность запустить вручную
|
||||
|
||||
jobs:
|
||||
build-linux:
|
||||
name: Build Linux Executable
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.9'
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install pyinstaller
|
||||
pip install -r requirements.txt
|
||||
|
||||
- name: Build Linux executable
|
||||
run: |
|
||||
make build-linux
|
||||
|
||||
- name: Test Linux executable
|
||||
run: |
|
||||
chmod +x dist/letsencrypt-regru
|
||||
dist/letsencrypt-regru --help
|
||||
|
||||
- name: Create Linux package
|
||||
run: |
|
||||
make package-linux
|
||||
|
||||
- name: Upload Linux artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: linux-executable
|
||||
path: dist/letsencrypt-regru-linux-x86_64.tar.gz
|
||||
|
||||
- name: Generate SHA256 checksum
|
||||
run: |
|
||||
cd dist
|
||||
sha256sum letsencrypt-regru-linux-x86_64.tar.gz > letsencrypt-regru-linux-x86_64.tar.gz.sha256
|
||||
|
||||
- name: Upload checksum
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: linux-checksum
|
||||
path: dist/letsencrypt-regru-linux-x86_64.tar.gz.sha256
|
||||
|
||||
build-windows:
|
||||
name: Build Windows Executable
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.9'
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install pyinstaller
|
||||
pip install -r requirements.txt
|
||||
|
||||
- name: Build Windows executable
|
||||
run: |
|
||||
make build-windows
|
||||
|
||||
- name: Test Windows executable
|
||||
run: |
|
||||
dist\letsencrypt-regru.exe --help
|
||||
|
||||
- name: Create Windows package
|
||||
run: |
|
||||
make package-windows
|
||||
|
||||
- name: Upload Windows artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: windows-executable
|
||||
path: dist/letsencrypt-regru-windows-x86_64.zip
|
||||
|
||||
- name: Generate SHA256 checksum
|
||||
run: |
|
||||
cd dist
|
||||
certutil -hashfile letsencrypt-regru-windows-x86_64.zip SHA256 > letsencrypt-regru-windows-x86_64.zip.sha256
|
||||
|
||||
- name: Upload checksum
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: windows-checksum
|
||||
path: dist/letsencrypt-regru-windows-x86_64.zip.sha256
|
||||
|
||||
create-release:
|
||||
name: Create GitHub Release
|
||||
needs: [build-linux, build-windows]
|
||||
runs-on: ubuntu-latest
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Download Linux artifact
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: linux-executable
|
||||
path: ./artifacts
|
||||
|
||||
- name: Download Linux checksum
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: linux-checksum
|
||||
path: ./artifacts
|
||||
|
||||
- name: Download Windows artifact
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: windows-executable
|
||||
path: ./artifacts
|
||||
|
||||
- name: Download Windows checksum
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: windows-checksum
|
||||
path: ./artifacts
|
||||
|
||||
- name: Create Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
files: |
|
||||
./artifacts/letsencrypt-regru-linux-x86_64.tar.gz
|
||||
./artifacts/letsencrypt-regru-linux-x86_64.tar.gz.sha256
|
||||
./artifacts/letsencrypt-regru-windows-x86_64.zip
|
||||
./artifacts/letsencrypt-regru-windows-x86_64.zip.sha256
|
||||
body: |
|
||||
## Let's Encrypt RegRu Manager ${{ github.ref_name }}
|
||||
|
||||
### 📦 Релизные пакеты
|
||||
|
||||
**Linux (Ubuntu/Debian/CentOS):**
|
||||
- `letsencrypt-regru-linux-x86_64.tar.gz` - Исполняемый файл + файлы
|
||||
- `letsencrypt-regru-linux-x86_64.tar.gz.sha256` - Контрольная сумма
|
||||
|
||||
**Windows:**
|
||||
- `letsencrypt-regru-windows-x86_64.zip` - Исполняемый файл + файлы
|
||||
- `letsencrypt-regru-windows-x86_64.zip.sha256` - Контрольная сумма
|
||||
|
||||
### 🚀 Быстрая установка
|
||||
|
||||
**Linux:**
|
||||
```bash
|
||||
wget https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}/letsencrypt-regru-linux-x86_64.tar.gz
|
||||
tar -xzf letsencrypt-regru-linux-x86_64.tar.gz
|
||||
sudo mv letsencrypt-regru /usr/local/bin/
|
||||
sudo chmod +x /usr/local/bin/letsencrypt-regru
|
||||
```
|
||||
|
||||
**Windows:**
|
||||
Скачайте `letsencrypt-regru-windows-x86_64.zip` и распакуйте.
|
||||
|
||||
### 📖 Документация
|
||||
|
||||
- [README.md](https://github.com/${{ github.repository }}/blob/${{ github.ref_name }}/README.md)
|
||||
- [BUILD_GUIDE.md](https://github.com/${{ github.repository }}/blob/${{ github.ref_name }}/BUILD_GUIDE.md)
|
||||
- [INSTALL_GUIDE.md](https://github.com/${{ github.repository }}/blob/${{ github.ref_name }}/docs/INSTALL_GUIDE.md)
|
||||
|
||||
### ⚠️ Важно
|
||||
|
||||
- Исполняемые файлы требуют установленного `certbot` в системе
|
||||
- Linux версия требует права root (sudo)
|
||||
- Windows версия не поддерживает certbot напрямую (используйте WSL)
|
||||
|
||||
### 🔐 Проверка контрольных сумм
|
||||
|
||||
**Linux:**
|
||||
```bash
|
||||
sha256sum -c letsencrypt-regru-linux-x86_64.tar.gz.sha256
|
||||
```
|
||||
|
||||
**Windows:**
|
||||
```powershell
|
||||
certutil -hashfile letsencrypt-regru-windows-x86_64.zip SHA256
|
||||
```
|
||||
draft: false
|
||||
prerelease: false
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -0,0 +1,234 @@
|
||||
name: "Deploy scripts to remote server"
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
ref:
|
||||
description: "Branch/tag/SHA for deployment"
|
||||
required: false
|
||||
default: "master"
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
name: "Upload and deploy on 192.168.10.14"
|
||||
runs-on: native
|
||||
|
||||
steps:
|
||||
- name: "Checkout repository"
|
||||
shell: bash
|
||||
env:
|
||||
GIT_TOKEN: ${{ secrets.GIT_TOKEN }}
|
||||
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
TOKEN="${GIT_TOKEN:-$GITEA_TOKEN}"
|
||||
if [ -z "${TOKEN}" ]; then
|
||||
echo "ERROR: GIT_TOKEN (or GITEA_TOKEN) secret is required"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
REF="${{ github.event.inputs.ref || 'master' }}"
|
||||
SERVER="${{ github.server_url }}"
|
||||
REPO="${{ github.repository }}"
|
||||
HOST="${SERVER#https://}"
|
||||
HOST="${HOST#http://}"
|
||||
|
||||
if [ "${HOST}" = "github.com" ]; then
|
||||
CLONE_URL="https://x-access-token:${TOKEN}@${HOST}/${REPO}.git"
|
||||
else
|
||||
CLONE_URL="https://${TOKEN}@${HOST}/${REPO}.git"
|
||||
fi
|
||||
|
||||
git clone --branch "${REF}" --depth 1 "${CLONE_URL}" . 2>&1 | grep -F -v "${TOKEN}" || true
|
||||
echo ">>> Source checked out: $(git log --oneline -1)"
|
||||
|
||||
- name: "Validate deployment secrets"
|
||||
shell: bash
|
||||
env:
|
||||
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
|
||||
DEPLOY_PORT: ${{ secrets.DEPLOY_PORT }}
|
||||
DEPLOY_USER: ${{ secrets.DEPLOY_USER }}
|
||||
DEPLOY_PATH: ${{ secrets.DEPLOY_PATH }}
|
||||
DEPLOY_SERVICE: ${{ secrets.DEPLOY_SERVICE }}
|
||||
DEPLOY_SSH_PRIVATE_KEY: ${{ secrets.DEPLOY_SSH_PRIVATE_KEY }}
|
||||
DEPLOY_SSH_KNOWN_HOSTS: ${{ secrets.DEPLOY_SSH_KNOWN_HOSTS }}
|
||||
CFG_REGRU_USERNAME: ${{ secrets.CFG_REGRU_USERNAME }}
|
||||
CFG_REGRU_PASSWORD: ${{ secrets.CFG_REGRU_PASSWORD }}
|
||||
CFG_EMAIL: ${{ secrets.CFG_EMAIL }}
|
||||
CFG_DOMAINS: ${{ secrets.CFG_DOMAINS }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
: "${DEPLOY_HOST:?DEPLOY_HOST secret is required}"
|
||||
: "${DEPLOY_PORT:?DEPLOY_PORT secret is required}"
|
||||
: "${DEPLOY_USER:?DEPLOY_USER secret is required}"
|
||||
: "${DEPLOY_PATH:?DEPLOY_PATH secret is required}"
|
||||
: "${DEPLOY_SERVICE:?DEPLOY_SERVICE secret is required}"
|
||||
: "${DEPLOY_SSH_PRIVATE_KEY:?DEPLOY_SSH_PRIVATE_KEY secret is required}"
|
||||
: "${CFG_REGRU_USERNAME:?CFG_REGRU_USERNAME secret is required}"
|
||||
: "${CFG_REGRU_PASSWORD:?CFG_REGRU_PASSWORD secret is required}"
|
||||
: "${CFG_EMAIL:?CFG_EMAIL secret is required}"
|
||||
: "${CFG_DOMAINS:?CFG_DOMAINS secret is required}"
|
||||
|
||||
if [ "${DEPLOY_HOST}" != "192.168.10.14" ]; then
|
||||
echo "ERROR: DEPLOY_HOST must be 192.168.10.14 for this workflow"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ">>> Secrets validation passed"
|
||||
|
||||
- name: "Create deployment archive"
|
||||
shell: bash
|
||||
env:
|
||||
CFG_REGRU_USERNAME: ${{ secrets.CFG_REGRU_USERNAME }}
|
||||
CFG_REGRU_PASSWORD: ${{ secrets.CFG_REGRU_PASSWORD }}
|
||||
CFG_DOMAIN: ${{ secrets.CFG_DOMAIN }}
|
||||
CFG_DOMAINS: ${{ secrets.CFG_DOMAINS }}
|
||||
CFG_WILDCARD: ${{ secrets.CFG_WILDCARD }}
|
||||
CFG_EMAIL: ${{ secrets.CFG_EMAIL }}
|
||||
CFG_CERT_DIR: ${{ secrets.CFG_CERT_DIR }}
|
||||
CFG_LOG_FILE: ${{ secrets.CFG_LOG_FILE }}
|
||||
CFG_DNS_PROPAGATION_WAIT: ${{ secrets.CFG_DNS_PROPAGATION_WAIT }}
|
||||
CFG_DNS_CHECK_ATTEMPTS: ${{ secrets.CFG_DNS_CHECK_ATTEMPTS }}
|
||||
CFG_DNS_CHECK_INTERVAL: ${{ secrets.CFG_DNS_CHECK_INTERVAL }}
|
||||
CFG_RENEWAL_DAYS: ${{ secrets.CFG_RENEWAL_DAYS }}
|
||||
CFG_NPM_ENABLED: ${{ secrets.CFG_NPM_ENABLED }}
|
||||
CFG_NPM_HOST: ${{ secrets.CFG_NPM_HOST }}
|
||||
CFG_NPM_EMAIL: ${{ secrets.CFG_NPM_EMAIL }}
|
||||
CFG_NPM_PASSWORD: ${{ secrets.CFG_NPM_PASSWORD }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
rm -rf .deploy-artifacts
|
||||
mkdir -p .deploy-artifacts
|
||||
|
||||
if command -v rsync >/dev/null 2>&1; then
|
||||
rsync -a \
|
||||
--exclude '.git/' \
|
||||
--exclude '.src-repo/' \
|
||||
--exclude '.wiki-repo/' \
|
||||
--exclude '.deploy-artifacts/' \
|
||||
./ .deploy-artifacts/repo/
|
||||
else
|
||||
cp -a . .deploy-artifacts/repo
|
||||
rm -rf .deploy-artifacts/repo/.git .deploy-artifacts/repo/.src-repo .deploy-artifacts/repo/.wiki-repo .deploy-artifacts/repo/.deploy-artifacts
|
||||
fi
|
||||
|
||||
python3 - <<'PY'
|
||||
import json
|
||||
import os
|
||||
|
||||
|
||||
def to_bool(value, default=False):
|
||||
if value is None or value == "":
|
||||
return default
|
||||
return str(value).strip().lower() in {"1", "true", "yes", "on"}
|
||||
|
||||
|
||||
def to_int(value, default):
|
||||
if value is None or value == "":
|
||||
return default
|
||||
return int(value)
|
||||
|
||||
|
||||
domains_raw = os.environ.get("CFG_DOMAINS", "").strip()
|
||||
if domains_raw.startswith("["):
|
||||
domains = json.loads(domains_raw)
|
||||
else:
|
||||
domains = [item.strip() for item in domains_raw.split(",") if item.strip()]
|
||||
|
||||
if not domains:
|
||||
raise RuntimeError("CFG_DOMAINS must contain at least one domain")
|
||||
|
||||
domain = os.environ.get("CFG_DOMAIN", "").strip() or domains[0]
|
||||
|
||||
config = {
|
||||
"regru_username": os.environ["CFG_REGRU_USERNAME"],
|
||||
"regru_password": os.environ["CFG_REGRU_PASSWORD"],
|
||||
"domain": domain,
|
||||
"domains": domains,
|
||||
"wildcard": to_bool(os.environ.get("CFG_WILDCARD"), True),
|
||||
"email": os.environ["CFG_EMAIL"],
|
||||
"cert_dir": os.environ.get("CFG_CERT_DIR") or "/etc/letsencrypt/live",
|
||||
"log_file": os.environ.get("CFG_LOG_FILE") or "/var/log/letsencrypt_regru.log",
|
||||
"dns_propagation_wait": to_int(os.environ.get("CFG_DNS_PROPAGATION_WAIT"), 60),
|
||||
"dns_check_attempts": to_int(os.environ.get("CFG_DNS_CHECK_ATTEMPTS"), 10),
|
||||
"dns_check_interval": to_int(os.environ.get("CFG_DNS_CHECK_INTERVAL"), 10),
|
||||
"renewal_days": to_int(os.environ.get("CFG_RENEWAL_DAYS"), 30),
|
||||
"npm_enabled": to_bool(os.environ.get("CFG_NPM_ENABLED"), True),
|
||||
"npm_host": os.environ.get("CFG_NPM_HOST") or "",
|
||||
"npm_email": os.environ.get("CFG_NPM_EMAIL") or "",
|
||||
"npm_password": os.environ.get("CFG_NPM_PASSWORD") or "",
|
||||
}
|
||||
|
||||
output_path = os.path.join(".deploy-artifacts", "repo", "config.json")
|
||||
with open(output_path, "w", encoding="utf-8") as file:
|
||||
json.dump(config, file, ensure_ascii=False, indent=4)
|
||||
PY
|
||||
|
||||
tar -czf .deploy-artifacts/deploy.tar.gz -C .deploy-artifacts repo
|
||||
ls -lh .deploy-artifacts/deploy.tar.gz
|
||||
|
||||
- name: "Configure SSH client"
|
||||
shell: bash
|
||||
env:
|
||||
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
|
||||
DEPLOY_PORT: ${{ secrets.DEPLOY_PORT }}
|
||||
DEPLOY_USER: ${{ secrets.DEPLOY_USER }}
|
||||
DEPLOY_SSH_PRIVATE_KEY: ${{ secrets.DEPLOY_SSH_PRIVATE_KEY }}
|
||||
DEPLOY_SSH_KNOWN_HOSTS: ${{ secrets.DEPLOY_SSH_KNOWN_HOSTS }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
mkdir -p ~/.ssh
|
||||
chmod 700 ~/.ssh
|
||||
|
||||
printf '%s\n' "${DEPLOY_SSH_PRIVATE_KEY}" > ~/.ssh/id_ed25519
|
||||
chmod 600 ~/.ssh/id_ed25519
|
||||
|
||||
if [ -n "${DEPLOY_SSH_KNOWN_HOSTS}" ]; then
|
||||
printf '%s\n' "${DEPLOY_SSH_KNOWN_HOSTS}" > ~/.ssh/known_hosts
|
||||
else
|
||||
ssh-keyscan -p "${DEPLOY_PORT}" -H "${DEPLOY_HOST}" >> ~/.ssh/known_hosts 2>/dev/null
|
||||
fi
|
||||
chmod 644 ~/.ssh/known_hosts
|
||||
|
||||
{
|
||||
echo "Host deploy-target"
|
||||
echo " HostName ${DEPLOY_HOST}"
|
||||
echo " Port ${DEPLOY_PORT}"
|
||||
echo " User ${DEPLOY_USER}"
|
||||
echo " IdentityFile ~/.ssh/id_ed25519"
|
||||
echo " StrictHostKeyChecking yes"
|
||||
} > ~/.ssh/config
|
||||
chmod 600 ~/.ssh/config
|
||||
|
||||
ssh deploy-target "echo '>>> SSH connection ok: ' \"\$(hostname)\""
|
||||
|
||||
- name: "Upload deployment archive"
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
scp .deploy-artifacts/deploy.tar.gz deploy-target:/tmp/configure_nginx_manager_deploy.tar.gz
|
||||
|
||||
- name: "Deploy and restart remote service"
|
||||
shell: bash
|
||||
env:
|
||||
DEPLOY_PATH: ${{ secrets.DEPLOY_PATH }}
|
||||
DEPLOY_SERVICE: ${{ secrets.DEPLOY_SERVICE }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
ssh deploy-target "set -euo pipefail; \
|
||||
TMP_DIR=\"/tmp/configure_nginx_manager_deploy\"; \
|
||||
sudo rm -rf \"\${TMP_DIR}\"; \
|
||||
sudo mkdir -p \"\${TMP_DIR}\"; \
|
||||
sudo tar -xzf /tmp/configure_nginx_manager_deploy.tar.gz -C \"\${TMP_DIR}\"; \
|
||||
sudo mkdir -p \"${DEPLOY_PATH}\"; \
|
||||
sudo rsync -a --delete --exclude '.git/' \"\${TMP_DIR}/repo/\" \"${DEPLOY_PATH}/\"; \
|
||||
sudo rm -rf \"\${TMP_DIR}\" /tmp/configure_nginx_manager_deploy.tar.gz; \
|
||||
sudo systemctl daemon-reload; \
|
||||
sudo systemctl restart \"${DEPLOY_SERVICE}\"; \
|
||||
sudo systemctl enable \"${DEPLOY_SERVICE}\"; \
|
||||
sudo systemctl --no-pager --full status \"${DEPLOY_SERVICE}\" | head -n 30"
|
||||
@@ -0,0 +1,297 @@
|
||||
name: "Релиз: архив исходников"
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "v*"
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tag:
|
||||
description: "Тег релиза (например: v2.2.0)"
|
||||
required: true
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
env:
|
||||
DIST_DIR: dist
|
||||
|
||||
jobs:
|
||||
release:
|
||||
name: "Упаковка и публикация релиза"
|
||||
runs-on: native
|
||||
|
||||
steps:
|
||||
- name: "Получение исходного кода"
|
||||
shell: bash
|
||||
env:
|
||||
GIT_TOKEN: ${{ secrets.GIT_TOKEN }}
|
||||
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
TOKEN="${GIT_TOKEN:-$GITEA_TOKEN}"
|
||||
SERVER="${{ github.server_url }}"
|
||||
REPO="${{ github.repository }}"
|
||||
HOST="${SERVER#https://}"
|
||||
HOST="${HOST#http://}"
|
||||
|
||||
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
||||
TAG="${{ github.event.inputs.tag }}"
|
||||
else
|
||||
TAG="${GITHUB_REF_NAME}"
|
||||
fi
|
||||
|
||||
if [ -z "${TAG}" ]; then
|
||||
echo "ОШИБКА: не удалось определить тег релиза."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ">>> Клонирование ${REPO} (тег: ${TAG})"
|
||||
|
||||
if [ -n "${TOKEN}" ]; then
|
||||
if [ "${HOST}" = "github.com" ]; then
|
||||
CLONE_URL="https://x-access-token:${TOKEN}@${HOST}/${REPO}.git"
|
||||
else
|
||||
CLONE_URL="https://${TOKEN}@${HOST}/${REPO}.git"
|
||||
fi
|
||||
else
|
||||
CLONE_URL="${SERVER}/${REPO}.git"
|
||||
fi
|
||||
|
||||
git clone --branch "${TAG}" --depth 1 "${CLONE_URL}" . 2>&1 | grep -F -v "${TOKEN:-}" || true
|
||||
git fetch --tags --force 2>/dev/null || true
|
||||
|
||||
echo "RELEASE_TAG=${TAG}" >> "$GITHUB_ENV"
|
||||
echo ">>> Исходный код получен: $(git log --oneline -1)"
|
||||
|
||||
- name: "Подготовка метаданных релиза"
|
||||
id: meta
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
TAG="${RELEASE_TAG}"
|
||||
VERSION="${TAG#v}"
|
||||
PREV_TAG=$(git describe --tags --abbrev=0 "${TAG}^" 2>/dev/null || true)
|
||||
|
||||
echo "tag=${TAG}" >> "$GITHUB_OUTPUT"
|
||||
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
|
||||
echo "prev_tag=${PREV_TAG}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
echo "══════════════════════════════════════"
|
||||
echo " Тег: ${TAG}"
|
||||
echo " Версия: ${VERSION}"
|
||||
echo " Пред. тег: ${PREV_TAG:-<первый релиз>}"
|
||||
echo " Коммит: ${GITHUB_SHA:0:8}"
|
||||
echo "══════════════════════════════════════"
|
||||
|
||||
- name: "Создание архивов исходного кода"
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
TAG="${{ steps.meta.outputs.tag }}"
|
||||
REPO_NAME="${GITHUB_REPOSITORY##*/}"
|
||||
ARCHIVE_BASE="${REPO_NAME}-${TAG}"
|
||||
|
||||
rm -rf .release-work "${DIST_DIR}"
|
||||
mkdir -p .release-work "${DIST_DIR}"
|
||||
|
||||
if command -v rsync >/dev/null 2>&1; then
|
||||
rsync -a \
|
||||
--exclude '.git/' \
|
||||
--exclude '.src-repo/' \
|
||||
--exclude '.wiki-repo/' \
|
||||
--exclude '.release-work/' \
|
||||
--exclude "${DIST_DIR}/" \
|
||||
./ ".release-work/${ARCHIVE_BASE}/"
|
||||
else
|
||||
cp -a . ".release-work/${ARCHIVE_BASE}"
|
||||
rm -rf \
|
||||
".release-work/${ARCHIVE_BASE}/.git" \
|
||||
".release-work/${ARCHIVE_BASE}/.src-repo" \
|
||||
".release-work/${ARCHIVE_BASE}/.wiki-repo" \
|
||||
".release-work/${ARCHIVE_BASE}/.release-work" \
|
||||
".release-work/${ARCHIVE_BASE}/${DIST_DIR}"
|
||||
fi
|
||||
|
||||
tar -czf "${DIST_DIR}/${ARCHIVE_BASE}.tar.gz" -C .release-work "${ARCHIVE_BASE}"
|
||||
|
||||
if command -v zip >/dev/null 2>&1; then
|
||||
(
|
||||
cd .release-work
|
||||
zip -qr "../${DIST_DIR}/${ARCHIVE_BASE}.zip" "${ARCHIVE_BASE}"
|
||||
)
|
||||
else
|
||||
ARCHIVE_BASE="${ARCHIVE_BASE}" DIST_DIR="${DIST_DIR}" python3 - <<'PY'
|
||||
import os
|
||||
import zipfile
|
||||
|
||||
base = os.environ["ARCHIVE_BASE"]
|
||||
src = os.path.join(".release-work", base)
|
||||
dst = os.path.join(os.environ["DIST_DIR"], f"{base}.zip")
|
||||
|
||||
with zipfile.ZipFile(dst, "w", zipfile.ZIP_DEFLATED) as zf:
|
||||
for root, _, files in os.walk(src):
|
||||
for file_name in files:
|
||||
full = os.path.join(root, file_name)
|
||||
arc = os.path.relpath(full, ".release-work")
|
||||
zf.write(full, arc)
|
||||
PY
|
||||
fi
|
||||
|
||||
sha256sum "${DIST_DIR}"/* > "${DIST_DIR}/checksums-sha256.txt"
|
||||
|
||||
echo "ARCHIVE_BASE=${ARCHIVE_BASE}" >> "$GITHUB_ENV"
|
||||
echo ">>> Артефакты релиза:"
|
||||
ls -lh "${DIST_DIR}"
|
||||
|
||||
- name: "Генерация описания релиза"
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
TAG="${{ steps.meta.outputs.tag }}"
|
||||
VERSION="${{ steps.meta.outputs.version }}"
|
||||
PREV_TAG="${{ steps.meta.outputs.prev_tag }}"
|
||||
DATE_UTC=$(date -u '+%Y-%m-%d %H:%M UTC')
|
||||
|
||||
CHANGELOG_FILE=""
|
||||
if [ -f "docs/ru/CHANGELOG.md" ]; then
|
||||
CHANGELOG_FILE="docs/ru/CHANGELOG.md"
|
||||
elif [ -f "docs/en/CHANGELOG_EN.md" ]; then
|
||||
CHANGELOG_FILE="docs/en/CHANGELOG_EN.md"
|
||||
fi
|
||||
|
||||
CHANGELOG_SECTION=""
|
||||
if [ -n "${CHANGELOG_FILE}" ]; then
|
||||
CHANGELOG_SECTION=$(awk -v ver="${VERSION}" '
|
||||
$0 ~ "^## \\[" ver "\\]" { in_section=1; next }
|
||||
/^## \[/ && in_section { exit }
|
||||
in_section { print }
|
||||
' "${CHANGELOG_FILE}")
|
||||
fi
|
||||
|
||||
if [ -n "${PREV_TAG}" ]; then
|
||||
COMMITS=$(git log --pretty=format:'- %s (%h)' "${PREV_TAG}..${TAG}" --no-merges | head -50)
|
||||
else
|
||||
COMMITS=$(git log --pretty=format:'- %s (%h)' --no-merges | head -50)
|
||||
fi
|
||||
|
||||
{
|
||||
echo "## ${TAG}"
|
||||
echo ""
|
||||
echo "Релиз скриптового проекта без компиляции бинарников."
|
||||
echo ""
|
||||
echo "### Что входит в релиз"
|
||||
echo "- Исходный код в форматах: ${ARCHIVE_BASE}.tar.gz, ${ARCHIVE_BASE}.zip"
|
||||
echo "- Контрольные суммы: checksums-sha256.txt"
|
||||
echo ""
|
||||
|
||||
if [ -n "${CHANGELOG_SECTION}" ]; then
|
||||
echo "### Что сделано (из CHANGELOG)"
|
||||
echo "${CHANGELOG_SECTION}"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
echo "### Коммиты релиза"
|
||||
if [ -n "${COMMITS}" ]; then
|
||||
echo "${COMMITS}"
|
||||
else
|
||||
echo "- Изменения не найдены"
|
||||
fi
|
||||
echo ""
|
||||
echo "---"
|
||||
echo ""
|
||||
echo "- Тег: ${TAG}"
|
||||
echo "- Коммит: ${GITHUB_SHA}"
|
||||
echo "- Дата (UTC): ${DATE_UTC}"
|
||||
} > /tmp/release_body.md
|
||||
|
||||
echo ">>> Сформировано описание релиза: /tmp/release_body.md"
|
||||
|
||||
- name: "Создание релиза и загрузка архивов"
|
||||
shell: bash
|
||||
env:
|
||||
GIT_TOKEN: ${{ secrets.GIT_TOKEN }}
|
||||
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
TOKEN="${GIT_TOKEN:-$GITEA_TOKEN}"
|
||||
if [ -z "${TOKEN}" ]; then
|
||||
echo "ОШИБКА: не задан секрет GIT_TOKEN (или GITEA_TOKEN)."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SERVER="${{ github.server_url }}"
|
||||
REPO="${{ github.repository }}"
|
||||
HOST="${SERVER#https://}"
|
||||
HOST="${HOST#http://}"
|
||||
TAG="${{ steps.meta.outputs.tag }}"
|
||||
|
||||
BODY_JSON=$(python3 - <<'PY'
|
||||
import json
|
||||
with open('/tmp/release_body.md', 'r', encoding='utf-8') as f:
|
||||
print(json.dumps(f.read(), ensure_ascii=False))
|
||||
PY
|
||||
)
|
||||
|
||||
if [ "${HOST}" = "github.com" ]; then
|
||||
CREATE_URL="https://api.github.com/repos/${REPO}/releases"
|
||||
AUTH_HEADER="Authorization: Bearer ${TOKEN}"
|
||||
EXTRA_HEADERS=(-H "Accept: application/vnd.github+json")
|
||||
else
|
||||
CREATE_URL="${SERVER}/api/v1/repos/${REPO}/releases"
|
||||
AUTH_HEADER="Authorization: token ${TOKEN}"
|
||||
EXTRA_HEADERS=()
|
||||
fi
|
||||
|
||||
RELEASE_JSON=$(curl -sf -X POST \
|
||||
-H "${AUTH_HEADER}" \
|
||||
-H "Content-Type: application/json" \
|
||||
"${EXTRA_HEADERS[@]}" \
|
||||
"${CREATE_URL}" \
|
||||
-d "{\"tag_name\":\"${TAG}\",\"target_commitish\":\"${GITHUB_SHA}\",\"name\":\"${TAG}\",\"body\":${BODY_JSON},\"draft\":false,\"prerelease\":false}")
|
||||
|
||||
RELEASE_ID=$(printf '%s' "${RELEASE_JSON}" | python3 -c "import sys,json; print(json.load(sys.stdin).get('id',''))")
|
||||
if [ -z "${RELEASE_ID}" ]; then
|
||||
echo "ОШИБКА: не удалось получить ID релиза"
|
||||
echo "${RELEASE_JSON}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "${HOST}" = "github.com" ]; then
|
||||
UPLOAD_BASE=$(printf '%s' "${RELEASE_JSON}" | python3 -c "import sys,json; print(json.load(sys.stdin).get('upload_url','').split('{')[0])")
|
||||
RELEASE_URL="https://github.com/${REPO}/releases/tag/${TAG}"
|
||||
else
|
||||
UPLOAD_BASE="${SERVER}/api/v1/repos/${REPO}/releases/${RELEASE_ID}/assets"
|
||||
RELEASE_URL="${SERVER}/${REPO}/releases/tag/${TAG}"
|
||||
fi
|
||||
|
||||
echo ">>> Загрузка файлов в релиз ${TAG}"
|
||||
for file in "${DIST_DIR}"/*; do
|
||||
[ -f "${file}" ] || continue
|
||||
name=$(basename "${file}")
|
||||
|
||||
if [ "${HOST}" = "github.com" ]; then
|
||||
curl -sf -X POST \
|
||||
-H "${AUTH_HEADER}" \
|
||||
-H "Content-Type: application/octet-stream" \
|
||||
"${EXTRA_HEADERS[@]}" \
|
||||
--data-binary @"${file}" \
|
||||
"${UPLOAD_BASE}?name=${name}" >/dev/null
|
||||
else
|
||||
curl -sf -X POST \
|
||||
-H "${AUTH_HEADER}" \
|
||||
-H "Content-Type: application/octet-stream" \
|
||||
--data-binary @"${file}" \
|
||||
"${UPLOAD_BASE}?name=${name}" >/dev/null
|
||||
fi
|
||||
|
||||
echo " ✓ ${name}"
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo ">>> Релиз опубликован: ${RELEASE_URL}"
|
||||
@@ -1,100 +0,0 @@
|
||||
name: Sync from Gitea
|
||||
|
||||
# Запускается вручную или по webhook от Gitea
|
||||
on:
|
||||
workflow_dispatch:
|
||||
repository_dispatch:
|
||||
types: [gitea-push]
|
||||
schedule:
|
||||
# Проверка каждый час
|
||||
- cron: '0 * * * *'
|
||||
|
||||
jobs:
|
||||
sync:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout GitHub repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Configure Git
|
||||
run: |
|
||||
git config --global user.name "Sync Bot"
|
||||
git config --global user.email "bot@example.com"
|
||||
|
||||
- name: Add Gitea remote
|
||||
env:
|
||||
GITEA_URL: ${{ secrets.GITEA_URL }}
|
||||
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||
run: |
|
||||
if [ -z "$GITEA_URL" ]; then
|
||||
echo "⚠️ GITEA_URL не настроен, пропускаем синхронизацию"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Добавляем Gitea remote с токеном
|
||||
git remote add gitea "https://oauth2:${GITEA_TOKEN}@${GITEA_URL#https://}"
|
||||
git remote -v
|
||||
|
||||
- name: Fetch from Gitea
|
||||
run: |
|
||||
if git remote | grep -q gitea; then
|
||||
echo "🔄 Получение изменений из Gitea..."
|
||||
git fetch gitea --tags
|
||||
else
|
||||
echo "⚠️ Gitea remote не настроен"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
- name: Check for new commits
|
||||
id: check
|
||||
run: |
|
||||
# Проверяем есть ли новые коммиты в Gitea
|
||||
LOCAL=$(git rev-parse HEAD)
|
||||
REMOTE=$(git rev-parse gitea/main 2>/dev/null || git rev-parse gitea/master 2>/dev/null || echo $LOCAL)
|
||||
|
||||
if [ "$LOCAL" != "$REMOTE" ]; then
|
||||
echo "new_commits=true" >> $GITHUB_OUTPUT
|
||||
echo "✅ Обнаружены новые изменения в Gitea"
|
||||
else
|
||||
echo "new_commits=false" >> $GITHUB_OUTPUT
|
||||
echo "ℹ️ Нет новых изменений"
|
||||
fi
|
||||
|
||||
- name: Merge changes from Gitea
|
||||
if: steps.check.outputs.new_commits == 'true'
|
||||
run: |
|
||||
# Определяем главную ветку
|
||||
if git show-ref --verify --quiet refs/remotes/gitea/main; then
|
||||
BRANCH="main"
|
||||
else
|
||||
BRANCH="master"
|
||||
fi
|
||||
|
||||
echo "🔀 Слияние изменений из gitea/${BRANCH}..."
|
||||
git merge "gitea/${BRANCH}" --allow-unrelated-histories -m "Sync from Gitea: $(date)"
|
||||
|
||||
- name: Push to GitHub
|
||||
if: steps.check.outputs.new_commits == 'true'
|
||||
run: |
|
||||
echo "⬆️ Отправка изменений в GitHub..."
|
||||
git push origin HEAD:main --force-with-lease
|
||||
git push origin --tags
|
||||
echo "✅ Синхронизация завершена"
|
||||
|
||||
- name: Summary
|
||||
if: always()
|
||||
run: |
|
||||
echo "## 🔄 Отчет о синхронизации" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
if [ "${{ steps.check.outputs.new_commits }}" == "true" ]; then
|
||||
echo "✅ **Статус**: Синхронизировано успешно" >> $GITHUB_STEP_SUMMARY
|
||||
echo "📦 **Коммиты**: Новые изменения получены и объединены" >> $GITHUB_STEP_SUMMARY
|
||||
else
|
||||
echo "ℹ️ **Статус**: Нет новых изменений" >> $GITHUB_STEP_SUMMARY
|
||||
fi
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "🕐 **Время**: $(date)" >> $GITHUB_STEP_SUMMARY
|
||||
@@ -0,0 +1,135 @@
|
||||
name: "Синхронизация Wiki"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- 'wiki/**'
|
||||
|
||||
jobs:
|
||||
sync-wiki:
|
||||
name: "Синхронизация Wiki"
|
||||
runs-on: native
|
||||
|
||||
steps:
|
||||
# ── Получение исходного кода (без actions/checkout) ────────────────
|
||||
- name: "Получение исходного кода"
|
||||
shell: bash
|
||||
env:
|
||||
GIT_TOKEN: ${{ secrets.GIT_TOKEN }}
|
||||
run: |
|
||||
set -e
|
||||
|
||||
SERVER="${{ github.server_url }}"
|
||||
REPO="${{ github.repository }}"
|
||||
HOST="${SERVER#https://}"
|
||||
HOST="${HOST#http://}"
|
||||
|
||||
redact() {
|
||||
local token="$1"
|
||||
if [ -n "${token}" ]; then
|
||||
grep -F -v "${token}" || true
|
||||
else
|
||||
cat
|
||||
fi
|
||||
}
|
||||
|
||||
echo ">>> Клонирование ${REPO}..."
|
||||
|
||||
if [ -d ".src-repo" ]; then
|
||||
rm -rf .src-repo
|
||||
fi
|
||||
|
||||
if [ -n "${GIT_TOKEN}" ]; then
|
||||
if [ "${HOST}" = "github.com" ]; then
|
||||
CLONE_URL="https://x-access-token:${GIT_TOKEN}@${HOST}/${REPO}.git"
|
||||
else
|
||||
CLONE_URL="https://${GIT_TOKEN}@${HOST}/${REPO}.git"
|
||||
fi
|
||||
else
|
||||
CLONE_URL="${SERVER}/${REPO}.git"
|
||||
fi
|
||||
|
||||
git clone --depth 1 "${CLONE_URL}" .src-repo 2>&1 | redact "${GIT_TOKEN}"
|
||||
echo ">>> Исходный код получен: $(cd .src-repo && git log --oneline -1)"
|
||||
|
||||
- name: "Проверка папки wiki/"
|
||||
shell: bash
|
||||
run: |
|
||||
if [ ! -d ".src-repo/wiki" ]; then
|
||||
echo "Папка wiki/ не найдена — синхронизация не требуется."
|
||||
exit 0
|
||||
fi
|
||||
echo ">>> Найдено файлов wiki: $(find .src-repo/wiki -type f | wc -l)"
|
||||
|
||||
- name: "Синхронизация wiki в DFGit Wiki"
|
||||
shell: bash
|
||||
env:
|
||||
GIT_TOKEN: ${{ secrets.GIT_TOKEN }}
|
||||
run: |
|
||||
set -e
|
||||
|
||||
redact() {
|
||||
local token="$1"
|
||||
if [ -n "${token}" ]; then
|
||||
grep -F -v "${token}" || true
|
||||
else
|
||||
cat
|
||||
fi
|
||||
}
|
||||
|
||||
if [ -z "${GIT_TOKEN}" ]; then
|
||||
echo "GIT_TOKEN не задан. Добавьте секрет в настройках: Settings -> Secrets -> Actions."
|
||||
echo "Пропуск синхронизации wiki без ошибки."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
SERVER="${{ github.server_url }}"
|
||||
REPO="${{ github.repository }}"
|
||||
HOST="${SERVER#https://}"
|
||||
HOST="${HOST#http://}"
|
||||
|
||||
WIKI_REPO_URL="${SERVER}/${REPO}.wiki.git"
|
||||
if [ "${HOST}" = "github.com" ]; then
|
||||
AUTH_WIKI_REPO_URL="https://x-access-token:${GIT_TOKEN}@${HOST}/${REPO}.wiki.git"
|
||||
else
|
||||
AUTH_WIKI_REPO_URL="https://oauth2:${GIT_TOKEN}@${HOST}/${REPO}.wiki.git"
|
||||
fi
|
||||
|
||||
echo ">>> Клонируем wiki-репозиторий..."
|
||||
if ! git clone --depth 1 "${AUTH_WIKI_REPO_URL}" .wiki-repo 2>&1 | redact "${GIT_TOKEN}"; then
|
||||
echo "Wiki-репозиторий недоступен или ещё не инициализирован: ${WIKI_REPO_URL}"
|
||||
echo "Пропуск синхронизации без ошибки."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# rsync или резервный вариант через cp
|
||||
if command -v rsync &>/dev/null; then
|
||||
rsync -a --delete --exclude '.git/' .src-repo/wiki/ .wiki-repo/
|
||||
else
|
||||
# Удаляем старые файлы (кроме .git) и копируем новые
|
||||
find .wiki-repo -mindepth 1 -not -path '.wiki-repo/.git/*' -not -name '.git' -delete 2>/dev/null || true
|
||||
cp -a .src-repo/wiki/* .wiki-repo/
|
||||
fi
|
||||
|
||||
cd .wiki-repo
|
||||
git add -A
|
||||
|
||||
if git diff --cached --quiet; then
|
||||
echo ">>> Изменений в wiki нет — пуш не требуется."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
git config user.name "dfgit-actions[bot]"
|
||||
git config user.email "dfgit-actions@local"
|
||||
|
||||
DEFAULT_BRANCH=$(git remote show origin 2>/dev/null | sed -n '/HEAD branch/s/.*: //p')
|
||||
if [ -z "${DEFAULT_BRANCH}" ]; then
|
||||
DEFAULT_BRANCH="master"
|
||||
fi
|
||||
|
||||
git commit -m "docs(wiki): синхронизация из master @ ${{ github.sha }}"
|
||||
git push origin "HEAD:${DEFAULT_BRANCH}" 2>&1 | redact "${GIT_TOKEN}"
|
||||
|
||||
echo ">>> Wiki синхронизирована в ветку ${DEFAULT_BRANCH}."
|
||||
@@ -2105,3 +2105,63 @@ chmod +x /path/to/repo.git/hooks/post-receive
|
||||
**Подробная документация**: См. [GITEA_SYNC.md](GITEA_SYNC.md)
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Deploy через GitHub Actions (с генерацией config.json)
|
||||
|
||||
Workflow `.github/workflows/deploy-service.yml` выполняет удалённый деплой на сервер `192.168.10.14` по SSH (ключ) и автоматически генерирует рабочий `config.json` из секретов.
|
||||
|
||||
### Как это работает
|
||||
|
||||
1. Клонируется указанный `ref` (по умолчанию `master`)
|
||||
2. Проверяются обязательные secrets
|
||||
3. На этапе упаковки генерируется `config.json` внутри деплой-пакета
|
||||
4. Архив отправляется на сервер по SSH
|
||||
5. Файлы раскатываются в `DEPLOY_PATH`, затем сервис перезапускается через `systemd`
|
||||
|
||||
### Обязательные secrets
|
||||
|
||||
#### Доступ к репозиторию
|
||||
- `GIT_TOKEN` (или `GITEA_TOKEN`)
|
||||
|
||||
#### SSH / деплой
|
||||
- `DEPLOY_HOST` = `192.168.10.14`
|
||||
- `DEPLOY_PORT` (обычно `22`)
|
||||
- `DEPLOY_USER`
|
||||
- `DEPLOY_SSH_PRIVATE_KEY` (приватный ключ для SSH)
|
||||
- `DEPLOY_PATH` (папка выкладки, например `/opt/configure_nginx_manager`)
|
||||
- `DEPLOY_SERVICE` (systemd unit, например `letsencrypt-regru.service`)
|
||||
|
||||
#### Данные для генерации `config.json`
|
||||
- `CFG_REGRU_USERNAME`
|
||||
- `CFG_REGRU_PASSWORD`
|
||||
- `CFG_EMAIL`
|
||||
- `CFG_DOMAINS` (JSON-массив или строка через запятую)
|
||||
|
||||
Примеры `CFG_DOMAINS`:
|
||||
- `[
|
||||
"dfv24.com",
|
||||
"pages.github.dfv24.com"
|
||||
]`
|
||||
- `dfv24.com,pages.github.dfv24.com`
|
||||
|
||||
### Опциональные secrets
|
||||
|
||||
- `DEPLOY_SSH_KNOWN_HOSTS`
|
||||
- `CFG_DOMAIN` (если не задан, берётся первый элемент из `CFG_DOMAINS`)
|
||||
- `CFG_WILDCARD` (`true/false`)
|
||||
- `CFG_CERT_DIR`
|
||||
- `CFG_LOG_FILE`
|
||||
- `CFG_DNS_PROPAGATION_WAIT`
|
||||
- `CFG_DNS_CHECK_ATTEMPTS`
|
||||
- `CFG_DNS_CHECK_INTERVAL`
|
||||
- `CFG_RENEWAL_DAYS`
|
||||
- `CFG_NPM_ENABLED` (`true/false`)
|
||||
- `CFG_NPM_HOST`
|
||||
- `CFG_NPM_EMAIL`
|
||||
- `CFG_NPM_PASSWORD`
|
||||
|
||||
### Запуск
|
||||
|
||||
Запустите вручную workflow `Deploy scripts to remote server` в Actions и при необходимости укажите `ref`.
|
||||
|
||||
---
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
# Secrets for Deployment and Configuration
|
||||
|
||||
This document provides a detailed description of the secrets required for deploying and configuring the `configure_nginx_manager` project. Each secret is listed with its purpose, example value, and any default behavior if applicable.
|
||||
|
||||
## Deployment Secrets
|
||||
|
||||
### DEPLOY_PORT
|
||||
- **Description**: The SSH port used to connect to the deployment server.
|
||||
- **Example**: `22`
|
||||
|
||||
### DEPLOY_USER
|
||||
- **Description**: The SSH user for deployment.
|
||||
- **Example**: `deploy`
|
||||
|
||||
### DEPLOY_SSH_PRIVATE_KEY
|
||||
- **Description**: The private SSH key used for authentication.
|
||||
- **Example**: Full PEM/OpenSSH block.
|
||||
|
||||
### DEPLOY_PATH
|
||||
- **Description**: The path on the server where the project will be deployed.
|
||||
- **Example**: `/opt/configure_nginx_manager`
|
||||
|
||||
### DEPLOY_SERVICE
|
||||
- **Description**: The name of the systemd unit to manage the service.
|
||||
- **Example**: `letsencrypt-regru.service`
|
||||
|
||||
### DEPLOY_SSH_KNOWN_HOSTS
|
||||
- **Description**: The `known_hosts` entry for the deployment server.
|
||||
- **Example**: `192.168.10.14 ssh-ed25519 AAAAC3...`
|
||||
|
||||
## Configuration Secrets
|
||||
|
||||
### CFG_REGRU_USERNAME
|
||||
- **Description**: The username for the reg.ru API.
|
||||
- **Example**: `my_reg_ru_login`
|
||||
|
||||
### CFG_REGRU_PASSWORD
|
||||
- **Description**: The password for the reg.ru API.
|
||||
- **Example**: `StrongPass123!`
|
||||
|
||||
### CFG_EMAIL
|
||||
- **Description**: The email address used for Let’s Encrypt notifications.
|
||||
- **Example**: `admin@dfv24.com`
|
||||
|
||||
### CFG_DOMAINS
|
||||
- **Description**: The domains to be managed. Can be provided as a JSON array or CSV.
|
||||
- **Example**: `["dfv24.com", "pages.github.dfv24.com"]`
|
||||
|
||||
### CFG_DOMAIN
|
||||
- **Description**: The primary domain. If empty, the first domain from `CFG_DOMAINS` is used.
|
||||
- **Example**: `dfv24.com`
|
||||
|
||||
### CFG_WILDCARD
|
||||
- **Description**: Whether to use wildcard certificates.
|
||||
- **Example**: `true`
|
||||
|
||||
### CFG_CERT_DIR
|
||||
- **Description**: The directory where certificates are stored.
|
||||
- **Default**: `/etc/letsencrypt/live`
|
||||
|
||||
### CFG_LOG_FILE
|
||||
- **Description**: The log file for the Let’s Encrypt process.
|
||||
- **Default**: `/var/log/letsencrypt_regru.log`
|
||||
|
||||
### CFG_DNS_PROPAGATION_WAIT
|
||||
- **Description**: The wait time for DNS propagation (in seconds).
|
||||
- **Default**: `60`
|
||||
|
||||
### CFG_DNS_CHECK_ATTEMPTS
|
||||
- **Description**: The number of attempts to check DNS propagation.
|
||||
- **Default**: `10`
|
||||
|
||||
### CFG_DNS_CHECK_INTERVAL
|
||||
- **Description**: The interval between DNS propagation checks (in seconds).
|
||||
- **Default**: `10`
|
||||
|
||||
### CFG_RENEWAL_DAYS
|
||||
- **Description**: The number of days before certificate renewal.
|
||||
- **Default**: `30`
|
||||
|
||||
### CFG_NPM_ENABLED
|
||||
- **Description**: Whether Nginx Proxy Manager (NPM) integration is enabled.
|
||||
- **Default**: `true`
|
||||
|
||||
### CFG_NPM_HOST
|
||||
- **Description**: The host URL for Nginx Proxy Manager.
|
||||
- **Example**: `http://192.168.10.14:81`
|
||||
|
||||
### CFG_NPM_EMAIL
|
||||
- **Description**: The email address for Nginx Proxy Manager.
|
||||
- **Example**: `admin@example.com`
|
||||
|
||||
### CFG_NPM_PASSWORD
|
||||
- **Description**: The password for Nginx Proxy Manager.
|
||||
- **Example**: `changeme`
|
||||
@@ -0,0 +1,43 @@
|
||||
# Сборка и релизы
|
||||
|
||||
Проект поддерживает сборку исполняемых файлов через PyInstaller.
|
||||
|
||||
## Быстрый старт
|
||||
|
||||
- `make build` — сборка для текущей ОС
|
||||
- `make build-linux` — сборка для Linux
|
||||
- `make build-windows` — сборка для Windows
|
||||
- `make release` — сборка + упаковка (linux tar.gz + windows zip) + checksums
|
||||
|
||||
Результаты появляются в папке `dist/`.
|
||||
|
||||
## Что важно понимать
|
||||
|
||||
- бинарник получается крупным (~40–60 МБ)
|
||||
- системный `certbot` всё равно нужен
|
||||
- кросс-компиляция (Windows→Linux, Linux→Windows) обычно не рекомендуется
|
||||
|
||||
## Пакеты релиза
|
||||
|
||||
- Linux: `letsencrypt-regru-linux-x86_64.tar.gz`
|
||||
- Windows: `letsencrypt-regru-windows-x86_64.zip`
|
||||
|
||||
## Автоматические релизы по тегам
|
||||
|
||||
Типовой сценарий:
|
||||
|
||||
1) создать тег:
|
||||
|
||||
`git tag -a v1.0.0 -m "Release 1.0.0"`
|
||||
|
||||
2) отправить тег:
|
||||
|
||||
`git push origin v1.0.0`
|
||||
|
||||
Далее CI (GitHub Actions / Gitea Actions) может автоматически:
|
||||
|
||||
- собрать артефакты
|
||||
- создать Release
|
||||
- прикрепить файлы
|
||||
|
||||
Подробности зависят от ваших workflows.
|
||||
@@ -0,0 +1,17 @@
|
||||
# Changelog
|
||||
|
||||
Краткое резюме по основным версиям (подробности — в `docs/ru/CHANGELOG.md`).
|
||||
|
||||
## 2.1.0 (2025‑10‑27)
|
||||
|
||||
- Добавлена генерация тестовых самоподписанных сертификатов (`--test-cert`, `make test-cert`, `test_certificate.sh`)
|
||||
- Расширена документация (testing guide, cheatsheet, project structure)
|
||||
|
||||
## 2.0.0 (2025‑10‑27)
|
||||
|
||||
- Интеграция с Nginx Proxy Manager (API)
|
||||
- Makefile, systemd timer/service, авто-режим
|
||||
|
||||
## 1.0.0 (2025‑10‑26)
|
||||
|
||||
- Первый релиз: LE+reg.ru DNS-01, bash/ps1 версии
|
||||
@@ -0,0 +1,62 @@
|
||||
# Команды и сценарии
|
||||
|
||||
## CLI: letsencrypt-regru
|
||||
|
||||
Основные режимы:
|
||||
|
||||
- `--check` — проверить срок действия и тип (staging/production)
|
||||
- `--info` — показать расширенную информацию по сертификату
|
||||
- `--obtain` — принудительно получить production сертификат
|
||||
- `--renew` — обновить существующий сертификат
|
||||
- `--auto` — авто-режим: создать/обновить по необходимости
|
||||
|
||||
Тесты/диагностика:
|
||||
|
||||
- `--staging` — тестовый сертификат LE staging (без лимитов)
|
||||
- `--test-cert` — самоподписанный тестовый сертификат (мгновенно, без интернета)
|
||||
- `--test-api` — проверка API reg.ru (IP, баланс)
|
||||
- `--test-dns` — полный цикл DNS TXT add → ожидание → nslookup → cleanup
|
||||
|
||||
Служебные (вызывает certbot):
|
||||
|
||||
- `--auth-hook`
|
||||
- `--cleanup-hook`
|
||||
|
||||
Дополнительно:
|
||||
|
||||
- `-c/--config <file>` — путь к конфигу
|
||||
- `-v/--verbose` — подробные логи
|
||||
- `--force-cleanup` — очистка lock-файлов certbot
|
||||
|
||||
### Мультидоменный режим
|
||||
|
||||
Если в конфиге указан `domains[]`, команды `--check/--info/--staging/--obtain/--renew/--auto/--test-*` будут выполняться **по всем доменам**.
|
||||
|
||||
## Makefile
|
||||
|
||||
Часто используемые команды:
|
||||
|
||||
- `make install` / `make uninstall`
|
||||
- `make test-cert`
|
||||
- `make obtain`
|
||||
- `make renew`
|
||||
- `make run` (аналог `--auto`)
|
||||
- `make status`
|
||||
- `make logs`
|
||||
|
||||
## Типовой workflow (рекомендуется)
|
||||
|
||||
1) Подготовка
|
||||
- `letsencrypt-regru --test-api -v`
|
||||
- `letsencrypt-regru --test-dns -v`
|
||||
|
||||
2) Тестирование без лимитов
|
||||
- `letsencrypt-regru --staging` **или** `letsencrypt-regru --test-cert`
|
||||
|
||||
3) Production
|
||||
- `letsencrypt-regru --obtain`
|
||||
|
||||
4) Автопродление
|
||||
- systemd timer или cron → `letsencrypt-regru --auto`
|
||||
|
||||
Если используете NPM — см. [Nginx_Proxy_Manager](Nginx_Proxy_Manager.md).
|
||||
@@ -0,0 +1,92 @@
|
||||
# Конфигурация
|
||||
|
||||
Проект использует JSON-конфиг (пример: `config.json.example`).
|
||||
|
||||
## Важно про мультидоменный режим
|
||||
|
||||
Скрипт поддерживает:
|
||||
|
||||
- один домен в поле `domain`
|
||||
- список доменов в поле `domains` (массив строк)
|
||||
- оба поля одновременно (будет объединение без дублей)
|
||||
|
||||
Пример:
|
||||
|
||||
```json
|
||||
{
|
||||
"regru_username": "your_username",
|
||||
"regru_password": "your_password",
|
||||
"domain": "dfv24.com",
|
||||
"domains": [
|
||||
"dfv24.com",
|
||||
"pages.github.dfv24.com"
|
||||
],
|
||||
"wildcard": true,
|
||||
"email": "admin@dfv24.com",
|
||||
"cert_dir": "/etc/letsencrypt/live",
|
||||
"log_file": "/var/log/letsencrypt_regru.log",
|
||||
"dns_propagation_wait": 60,
|
||||
"dns_check_attempts": 10,
|
||||
"dns_check_interval": 10,
|
||||
"renewal_days": 30,
|
||||
"npm_enabled": true,
|
||||
"npm_host": "http://192.168.10.14:81",
|
||||
"npm_email": "admin@example.com",
|
||||
"npm_password": "changeme"
|
||||
}
|
||||
```
|
||||
|
||||
## Параметры конфигурации
|
||||
|
||||
### reg.ru API
|
||||
|
||||
- `regru_username`, `regru_password`
|
||||
- учётные данные для API reg.ru
|
||||
- IP должен быть разрешён в настройках API (см. [RegRu_API_Troubleshooting](RegRu_API_Troubleshooting.md))
|
||||
|
||||
### Домены
|
||||
|
||||
- `domain`: основной домен (строка)
|
||||
- `domains`: массив доменов
|
||||
- `wildcard`: если `true`, скрипт будет запрашивать `-d <domain>` и `-d *.<domain>`
|
||||
- обратите внимание: этот флаг сейчас общий для всех доменов из массива
|
||||
|
||||
### Let’s Encrypt
|
||||
|
||||
- `email`: email для регистрации в Let’s Encrypt
|
||||
- `renewal_days`: порог автопродления (например, 30)
|
||||
|
||||
### DNS ожидание/проверки
|
||||
|
||||
- `dns_propagation_wait`: сколько секунд ждать после добавления TXT
|
||||
- `dns_check_attempts`: сколько попыток проверки через `nslookup`
|
||||
- `dns_check_interval`: интервал между попытками
|
||||
|
||||
### Пути
|
||||
|
||||
- `cert_dir`: базовая папка сертификатов (обычно `/etc/letsencrypt/live`)
|
||||
- `log_file`: файл логов
|
||||
|
||||
### Nginx Proxy Manager (опционально)
|
||||
|
||||
- `npm_enabled`: включить синхронизацию сертификатов в NPM
|
||||
- `npm_host`: URL NPM (пример: `http://10.10.10.14:81`)
|
||||
- `npm_email`, `npm_password`: учётные данные
|
||||
|
||||
Подробности: [Nginx_Proxy_Manager](Nginx_Proxy_Manager.md).
|
||||
|
||||
## Проверка конфига
|
||||
|
||||
- `letsencrypt-regru --test-api -v`
|
||||
- `letsencrypt-regru --test-dns -v`
|
||||
- `letsencrypt-regru --check -v`
|
||||
|
||||
## Где хранить конфиг
|
||||
|
||||
- храните конфиг с правами `600`
|
||||
- владелец: root
|
||||
|
||||
Пример:
|
||||
|
||||
- `sudo chmod 600 /etc/letsencrypt/regru_config.json`
|
||||
- `sudo chown root:root /etc/letsencrypt/regru_config.json`
|
||||
@@ -0,0 +1,95 @@
|
||||
# Deploy через Actions и Secrets
|
||||
|
||||
Эта страница описывает деплой через workflow `.github/workflows/deploy-service.yml`.
|
||||
|
||||
## Что делает workflow
|
||||
|
||||
- деплоит проект на сервер `192.168.10.14` по SSH (ключ)
|
||||
- перед деплоем генерирует `config.json` из secrets
|
||||
- копирует архив на сервер, распаковывает в `DEPLOY_PATH`
|
||||
- перезапускает systemd-сервис `DEPLOY_SERVICE`
|
||||
|
||||
## Обязательные secrets
|
||||
|
||||
### Доступ к репозиторию
|
||||
|
||||
- `GIT_TOKEN` (или `GITEA_TOKEN`)
|
||||
|
||||
### SSH и деплой
|
||||
|
||||
- `DEPLOY_HOST` — должен быть `192.168.10.14`
|
||||
- `DEPLOY_PORT` — обычно `22`
|
||||
- `DEPLOY_USER`
|
||||
- `DEPLOY_SSH_PRIVATE_KEY`
|
||||
- `DEPLOY_PATH`
|
||||
- `DEPLOY_SERVICE`
|
||||
|
||||
### Генерация config.json
|
||||
|
||||
- `CFG_REGRU_USERNAME`
|
||||
- `CFG_REGRU_PASSWORD`
|
||||
- `CFG_EMAIL`
|
||||
- `CFG_DOMAINS`
|
||||
|
||||
`CFG_DOMAINS` поддерживает два формата:
|
||||
|
||||
1) JSON-массив:
|
||||
|
||||
```json
|
||||
["dfv24.com", "pages.github.dfv24.com"]
|
||||
```
|
||||
|
||||
2) строка через запятую:
|
||||
|
||||
```text
|
||||
dfv24.com,pages.github.dfv24.com
|
||||
```
|
||||
|
||||
Если `CFG_DOMAIN` не указан, в поле `domain` берётся первый домен из `CFG_DOMAINS`.
|
||||
|
||||
## Опциональные secrets
|
||||
|
||||
- `DEPLOY_SSH_KNOWN_HOSTS`
|
||||
- `CFG_DOMAIN`
|
||||
- `CFG_WILDCARD`
|
||||
- `CFG_CERT_DIR`
|
||||
- `CFG_LOG_FILE`
|
||||
- `CFG_DNS_PROPAGATION_WAIT`
|
||||
- `CFG_DNS_CHECK_ATTEMPTS`
|
||||
- `CFG_DNS_CHECK_INTERVAL`
|
||||
- `CFG_RENEWAL_DAYS`
|
||||
- `CFG_NPM_ENABLED`
|
||||
- `CFG_NPM_HOST`
|
||||
- `CFG_NPM_EMAIL`
|
||||
- `CFG_NPM_PASSWORD`
|
||||
|
||||
## Соответствие полей config.json
|
||||
|
||||
- `CFG_REGRU_USERNAME` → `regru_username`
|
||||
- `CFG_REGRU_PASSWORD` → `regru_password`
|
||||
- `CFG_DOMAIN` / первый из `CFG_DOMAINS` → `domain`
|
||||
- `CFG_DOMAINS` → `domains`
|
||||
- `CFG_WILDCARD` → `wildcard`
|
||||
- `CFG_EMAIL` → `email`
|
||||
- `CFG_CERT_DIR` → `cert_dir`
|
||||
- `CFG_LOG_FILE` → `log_file`
|
||||
- `CFG_DNS_PROPAGATION_WAIT` → `dns_propagation_wait`
|
||||
- `CFG_DNS_CHECK_ATTEMPTS` → `dns_check_attempts`
|
||||
- `CFG_DNS_CHECK_INTERVAL` → `dns_check_interval`
|
||||
- `CFG_RENEWAL_DAYS` → `renewal_days`
|
||||
- `CFG_NPM_ENABLED` → `npm_enabled`
|
||||
- `CFG_NPM_HOST` → `npm_host`
|
||||
- `CFG_NPM_EMAIL` → `npm_email`
|
||||
- `CFG_NPM_PASSWORD` → `npm_password`
|
||||
|
||||
## Как запустить деплой
|
||||
|
||||
1. Откройте Actions
|
||||
2. Запустите workflow `Deploy scripts to remote server`
|
||||
3. При необходимости задайте `ref` (ветка/тег/коммит)
|
||||
|
||||
После завершения проверьте статус сервиса на сервере:
|
||||
|
||||
```bash
|
||||
sudo systemctl status letsencrypt-regru.service
|
||||
```
|
||||
@@ -0,0 +1,29 @@
|
||||
# Синхронизация Gitea → GitHub
|
||||
|
||||
Проект описывает несколько способов синхронизировать репозиторий из Gitea в GitHub после push.
|
||||
|
||||
## Варианты
|
||||
|
||||
1) Git Hooks (рекомендуется) — мгновенно
|
||||
2) GitHub Actions — 1–5 минут, гибко
|
||||
3) Gitea Mirror — просто, но по расписанию
|
||||
4) Два remote — локальный рабочий процесс
|
||||
|
||||
## Рекомендуемый способ: Git Hooks
|
||||
|
||||
Идея: на сервере Gitea в `hooks/post-receive` выполнить `git push` в GitHub.
|
||||
|
||||
Ключевые шаги:
|
||||
|
||||
- найти путь к bare-репозиторию на сервере Gitea
|
||||
- установить `post-receive` из `gitea-hooks/post-receive`
|
||||
- настроить аутентификацию (SSH ключ или HTTPS token)
|
||||
- вести лог (например `/var/log/gitea/github-sync.log`)
|
||||
|
||||
## Вариант: GitHub Actions
|
||||
|
||||
- настроить секреты (`GITEA_URL`, `GITEA_TOKEN`)
|
||||
- workflow по расписанию/ручному триггеру
|
||||
- опционально webhook из Gitea
|
||||
|
||||
Подробные пошаговые инструкции — в исходном документе `docs/ru/GITEA_SYNC.md`.
|
||||
@@ -0,0 +1,60 @@
|
||||
# SSL Certificate Manager (Let's Encrypt + reg.ru) — Wiki (RU)
|
||||
|
||||
Это Wiki проекта **configure_nginx_manager**: автоматическое получение и продление SSL-сертификатов Let's Encrypt через **DNS-01** (API **reg.ru**) с опциональной синхронизацией сертификатов в **Nginx Proxy Manager (NPM)**.
|
||||
|
||||
## Что умеет проект
|
||||
|
||||
- Получение **production** сертификатов Let's Encrypt (DNS-01) для доменов reg.ru
|
||||
- Поддержка **wildcard** (например, `*.example.com`)
|
||||
- Автопроверка и автопродление (cron/systemd)
|
||||
- Диагностика: `--test-api`, `--test-dns`
|
||||
- Тестовые самоподписанные сертификаты для разработки: `--test-cert` (без лимитов LE)
|
||||
- (Опционально) Автозагрузка/обновление сертификатов в NPM по API
|
||||
- **Мультидоменный режим**: один конфиг → несколько доменов (`domains[]`)
|
||||
|
||||
## Быстрый старт
|
||||
|
||||
1) Установка
|
||||
- См. страницу: [Installation](Installation.md)
|
||||
|
||||
2) Конфигурация
|
||||
- См. страницу: [Configuration](Configuration.md)
|
||||
|
||||
3) Проверка доступа к API и DNS
|
||||
- `letsencrypt-regru --test-api -v`
|
||||
- `letsencrypt-regru --test-dns -v`
|
||||
|
||||
4) Тестирование без лимитов
|
||||
- `letsencrypt-regru --test-cert`
|
||||
|
||||
5) Production сертификат
|
||||
- `letsencrypt-regru --obtain`
|
||||
|
||||
6) Автопродление
|
||||
- `letsencrypt-regru --auto` (обычно запускается systemd timer’ом)
|
||||
|
||||
## Навигация
|
||||
|
||||
- [Installation](Installation.md)
|
||||
- [Configuration](Configuration.md)
|
||||
- [Commands](Commands.md)
|
||||
- [LetsEncrypt Workflow](LetsEncrypt_Workflow.md)
|
||||
- [Nginx Proxy Manager](Nginx_Proxy_Manager.md)
|
||||
- [Testing](Testing.md)
|
||||
- [Reg.ru API Troubleshooting](RegRu_API_Troubleshooting.md)
|
||||
- [Build & Release](Build_and_Release.md)
|
||||
- [Deploy и Secrets](Deploy_Actions_Secrets.md)
|
||||
- [Project Structure](Project_Structure.md)
|
||||
- [Gitea → GitHub Sync](Gitea_Sync.md)
|
||||
- [Changelog](Changelog.md)
|
||||
|
||||
## Примечания по лимитам Let's Encrypt
|
||||
|
||||
- Production: обычно **до 5 сертификатов/неделю на домен**
|
||||
- Для отладки автоматизации используйте:
|
||||
- `--staging` (LE staging, без лимитов)
|
||||
- `--test-cert` (самоподписанный, мгновенно)
|
||||
|
||||
---
|
||||
|
||||
Источник: документация в `docs/ru/` и актуальное поведение CLI.
|
||||
@@ -0,0 +1,59 @@
|
||||
# Установка
|
||||
|
||||
Есть два основных пути установки:
|
||||
|
||||
1) Автоустановщик `letsencrypt_regru.sh` (самый простой)
|
||||
2) Установка через `Makefile` (контролируемый сценарий)
|
||||
|
||||
## Требования
|
||||
|
||||
- Linux (Debian/Ubuntu/CentOS/RHEL/Fedora)
|
||||
- Root (запуск через `sudo`)
|
||||
- Python 3.6+ (для исходников) или готовый бинарник
|
||||
- certbot (системный)
|
||||
- Доступ к API reg.ru (разрешённый IP, корректные учётные данные)
|
||||
|
||||
## Вариант A — автоустановщик (рекомендуется)
|
||||
|
||||
### Установка одной командой
|
||||
|
||||
- Через `curl`:
|
||||
|
||||
`sudo bash -c "$(curl -fsSL https://github.com/DFofanov/configure_nginx_manager/raw/refs/heads/master/letsencrypt_regru.sh)"`
|
||||
|
||||
### Что делает установщик
|
||||
|
||||
- Ставит зависимости
|
||||
- Создаёт виртуальное окружение
|
||||
- Помогает интерактивно собрать конфиг
|
||||
- Настраивает systemd service/timer
|
||||
- Добавляет глобальную команду `letsencrypt-regru`
|
||||
|
||||
## Вариант B — через Makefile
|
||||
|
||||
Типовой сценарий:
|
||||
|
||||
- `sudo make install`
|
||||
- отредактировать конфиг (см. [Configuration](Configuration.md))
|
||||
- `sudo make test-cert` (проверка без лимитов)
|
||||
- `sudo make obtain` (production сертификат)
|
||||
|
||||
Полный список команд: [Commands](Commands.md).
|
||||
|
||||
## Где лежат файлы после установки
|
||||
|
||||
(типовая структура, может отличаться от ваших путей)
|
||||
|
||||
- Приложение: `/opt/letsencrypt-regru/`
|
||||
- Конфиг: `/etc/letsencrypt/regru_config.json` (или `/etc/letsencrypt-regru/config.json` — зависит от сценария)
|
||||
- Сертификаты: `/etc/letsencrypt/live/<domain>/`
|
||||
- Логи: `/var/log/letsencrypt_regru.log` (или `/var/log/letsencrypt-regru/letsencrypt_regru.log`)
|
||||
- systemd units: `/etc/systemd/system/letsencrypt-regru.service` и `.timer`
|
||||
|
||||
## Проверка после установки
|
||||
|
||||
- `letsencrypt-regru --help`
|
||||
- `letsencrypt-regru --test-api -v`
|
||||
- `letsencrypt-regru --test-dns -v`
|
||||
|
||||
Если ловите ошибку `Access to API from this IP denied`, см. [RegRu_API_Troubleshooting](RegRu_API_Troubleshooting.md).
|
||||
@@ -0,0 +1,64 @@
|
||||
# Алгоритм получения и продления сертификата
|
||||
|
||||
Эта страница описывает реальный алгоритм работы скрипта (по документации и текущему коду).
|
||||
|
||||
## Получение сертификата (production / staging)
|
||||
|
||||
Команды:
|
||||
|
||||
- production: `--obtain`
|
||||
- staging: `--staging`
|
||||
|
||||
Шаги:
|
||||
|
||||
1) Проверка наличия certbot
|
||||
2) Формирование списка доменов для certbot:
|
||||
- всегда: `<domain>`
|
||||
- если `wildcard=true`: `*.<domain>`
|
||||
3) Запуск `certbot certonly --manual --preferred-challenges dns`
|
||||
4) Certbot вызывает hook’и:
|
||||
- auth-hook: добавляет TXT запись `_acme-challenge` через API reg.ru
|
||||
- cleanup-hook: удаляет TXT запись
|
||||
5) После успеха сертификаты появляются в `cert_dir/<domain>/`:
|
||||
- `privkey.pem`, `cert.pem`, `chain.pem`, `fullchain.pem`
|
||||
6) (опционально) синхронизация в NPM
|
||||
7) (опционально) перезагрузка веб-сервиса (nginx/apache)
|
||||
|
||||
### Про TXT для поддоменов
|
||||
|
||||
Если вы выпускаете сертификат для поддомена вида `pages.github.example.com`, TXT должен создаваться в зоне зарегистрированного домена `example.com` как:
|
||||
|
||||
- `_acme-challenge.pages.github.example.com`
|
||||
|
||||
Скрипт учитывает это, выбирая зарегистрированный домен по списку доменов в конфиге.
|
||||
|
||||
## Продление сертификата
|
||||
|
||||
Команда:
|
||||
|
||||
- `--renew`
|
||||
|
||||
Скрипт запускает `certbot renew` для конкретного `--cert-name <domain>` и использует те же hook’и (auth/cleanup) с корректным `--config`.
|
||||
|
||||
## Авто-режим
|
||||
|
||||
Команда:
|
||||
|
||||
- `--auto`
|
||||
|
||||
Логика по каждому домену из конфига:
|
||||
|
||||
- если сертификата нет → получить новый
|
||||
- если срок меньше `renewal_days` → продлить
|
||||
- иначе → ничего не делать (опционально проверить наличие в NPM)
|
||||
|
||||
Возврат кода:
|
||||
|
||||
- `0` — всё успешно
|
||||
- `1` — были ошибки
|
||||
|
||||
## Где смотреть логи
|
||||
|
||||
- Логи скрипта: путь `log_file` из конфига
|
||||
- Логи certbot: обычно `/var/log/letsencrypt/letsencrypt.log`
|
||||
- systemd: `journalctl -u letsencrypt-regru -f`
|
||||
@@ -0,0 +1,112 @@
|
||||
# Интеграция с Nginx Proxy Manager (NPM)
|
||||
|
||||
Проект умеет автоматически загружать (или обновлять) сертификаты в NPM через его API.
|
||||
|
||||
## Включение
|
||||
|
||||
В конфиге:
|
||||
|
||||
- `npm_enabled: true`
|
||||
- `npm_host`: например `http://192.168.10.14:81`
|
||||
- `npm_email`, `npm_password`
|
||||
|
||||
После этого:
|
||||
|
||||
- `--obtain`, `--renew`, `--auto`, `--test-cert` будут пытаться синхронизировать сертификат в NPM.
|
||||
|
||||
## Как работает синхронизация
|
||||
|
||||
1) Скрипт логинится в NPM (`/api/tokens`)
|
||||
2) Получает список сертификатов
|
||||
3) Ищет сертификат по домену (учитывает `<domain>` и `*.<domain>`)
|
||||
4) Если найден — обновляет, иначе — загружает новый
|
||||
|
||||
### Про “дубликаты” сертификатов
|
||||
|
||||
Иногда NPM сразу после загрузки ещё не распарсил домены (поле `domain_names` пустое). Скрипт дополнительно пытается сопоставлять по `nice_name`, чтобы не плодить дубли.
|
||||
|
||||
Команда для диагностики:
|
||||
|
||||
- `--list-npm` — показывает сертификаты и подсвечивает дубликаты
|
||||
- `--delete-npm <ID>` — удаляет сертификат по ID
|
||||
|
||||
## Ручная загрузка существующего сертификата
|
||||
|
||||
- `--upload-npm <DOMAIN>`
|
||||
|
||||
Скрипт возьмёт `fullchain.pem` и `privkey.pem` из `cert_dir/<DOMAIN>/` и загрузит/обновит сертификат в NPM.
|
||||
|
||||
## Один wildcard сертификат на много поддоменов
|
||||
|
||||
Практический сценарий:
|
||||
|
||||
- Получить сертификат на `example.com` + `*.example.com`
|
||||
- В NPM импортировать/использовать этот сертификат для всех Proxy Hosts
|
||||
|
||||
Обратите внимание:
|
||||
|
||||
- для wildcard Let’s Encrypt нужен DNS-01 challenge
|
||||
- в NPM можно использовать либо встроенный Let’s Encrypt, либо этот проект как внешний менеджер и синхронизатор
|
||||
|
||||
## Пошагово: использовать один wildcard сертификат для всех Proxy Hosts
|
||||
|
||||
Ниже — практический сценарий, когда вам нужен один сертификат (например, `*.example.com`) и вы хотите назначать его на все хосты.
|
||||
|
||||
### Вариант A: сертификат выдаёт этот проект (рекомендуется при reg.ru DNS-01)
|
||||
|
||||
1) Убедитесь, что DNS API reg.ru работает:
|
||||
|
||||
- `letsencrypt-regru --test-api -v`
|
||||
- `letsencrypt-regru --test-dns -v`
|
||||
|
||||
2) Получите production сертификат:
|
||||
|
||||
- `letsencrypt-regru --obtain`
|
||||
|
||||
3) Если `npm_enabled=true`, сертификат автоматически появится в NPM.
|
||||
|
||||
4) В NPM:
|
||||
|
||||
- Proxy Hosts → Add/Edit Proxy Host
|
||||
- SSL → выберите сертификат (обычно “Custom/Other”)
|
||||
- включите нужные опции (Force SSL, HSTS по необходимости)
|
||||
|
||||
### Вариант B: сертификат выдаёт сам NPM
|
||||
|
||||
Этот вариант подходит, если NPM может сам пройти challenge.
|
||||
|
||||
1) SSL Certificates → Add SSL Certificate → Let’s Encrypt
|
||||
2) Domain Names: добавьте `example.com` и `*.example.com`
|
||||
3) Выберите challenge:
|
||||
|
||||
- HTTP-01: требует доступности NPM из интернета по 80/443 и корректных A/AAAA записей
|
||||
- DNS-01: требует поддерживаемого DNS provider в NPM
|
||||
|
||||
Если нужного DNS провайдера нет (или нет корректной интеграции для reg.ru), проще использовать этот проект как внешний DNS-01 менеджер.
|
||||
|
||||
### Вариант C: импорт уже существующего wildcard сертификата (Custom)
|
||||
|
||||
Если вы приобрели wildcard сертификат у CA или получили его другим способом:
|
||||
|
||||
1) SSL Certificates → Add SSL Certificate → Custom
|
||||
2) Вставьте:
|
||||
|
||||
- Certificate: сертификат + intermediate chain (если отдельно — добавьте подряд)
|
||||
- Key: приватный ключ
|
||||
|
||||
3) Сохраните и назначайте этот сертификат на Proxy Hosts.
|
||||
|
||||
## DNS записи для wildcard
|
||||
|
||||
Для проксирования поддоменов часто достаточно, чтобы DNS указывал на NPM:
|
||||
|
||||
- `example.com` → IP NPM
|
||||
- `*.example.com` → IP NPM
|
||||
|
||||
Точная схема зависит от вашей инфраструктуры.
|
||||
|
||||
## Траблшутинг
|
||||
|
||||
- “не логинится” → проверьте `npm_host` (http/https), креды, доступность
|
||||
- “сертификат не появился” → проверьте `npm_enabled`, логи скрипта
|
||||
- staging сертификаты: не предназначены для production (браузер не доверяет)
|
||||
@@ -0,0 +1,26 @@
|
||||
# Структура проекта
|
||||
|
||||
Ключевые файлы:
|
||||
|
||||
- `letsencrypt_regru_api.py` — основной Python-скрипт (API reg.ru + certbot + NPM)
|
||||
- `letsencrypt_regru.sh` — установщик и менеджер установки
|
||||
- `Makefile` — команды установки/обслуживания/сборки
|
||||
- `config.json.example` — пример конфигурации
|
||||
- `systemd/` — unit-файлы для автозапуска/таймера
|
||||
- `docs/ru/` — исходная документация (RU)
|
||||
|
||||
Скрипты:
|
||||
|
||||
- `letsencrypt_regru_dns.sh` — bash-вариант через плагин certbot-dns-regru
|
||||
- `letsencrypt_regru.ps1` — PowerShell-версия
|
||||
- `test_certificate.sh` — автономная генерация тестовых сертификатов через OpenSSL
|
||||
|
||||
Документация:
|
||||
|
||||
- `README.md` — основное руководство
|
||||
- `docs/ru/*` — дополнительные гайды (тестирование, сборка, синхронизация и т.д.)
|
||||
|
||||
## Автоматизация
|
||||
|
||||
- systemd timer обычно запускает `--auto` по расписанию (по умолчанию каждые 12 часов)
|
||||
- после успешного обновления может выполняться reload веб-сервиса
|
||||
@@ -0,0 +1,54 @@
|
||||
# Проблемы API reg.ru (DNS)
|
||||
|
||||
## Ошибка: “Access to API from this IP denied”
|
||||
|
||||
Причина: ваш текущий IP не разрешён в настройках API reg.ru.
|
||||
|
||||
### Диагностика
|
||||
|
||||
- `letsencrypt-regru --test-api`
|
||||
- или `curl -s https://ipinfo.io/ip`
|
||||
|
||||
### Решение (рекомендуется)
|
||||
|
||||
1) Личный кабинет reg.ru
|
||||
2) Настройки → Безопасность → API
|
||||
3) Добавить текущий IP в белый список
|
||||
4) Повторить `--test-api`
|
||||
|
||||
### Альтернатива
|
||||
|
||||
Отключить ограничения по IP (менее безопасно).
|
||||
|
||||
## Ошибка: “Invalid username or password”
|
||||
|
||||
- проверьте `regru_username`/`regru_password` в конфиге
|
||||
- проверьте права доступа к файлу конфига (600)
|
||||
|
||||
## Ошибка: “IP exceeded allowed connection rate”
|
||||
|
||||
API ограничивает частоту запросов.
|
||||
|
||||
Решения:
|
||||
|
||||
- подождать 5–10 минут
|
||||
- не запускать `--test-api` слишком часто
|
||||
- для мониторинга чаще используйте `--check`
|
||||
|
||||
## Таймауты
|
||||
|
||||
- проверьте интернет
|
||||
- проверьте firewall/proxy
|
||||
|
||||
## Логи для диагностики
|
||||
|
||||
- `log_file` из конфигурации
|
||||
- `/var/log/letsencrypt/letsencrypt.log` (certbot)
|
||||
|
||||
## Когда обращаться в поддержку reg.ru
|
||||
|
||||
Приготовьте:
|
||||
|
||||
- ваш IP
|
||||
- точный текст ошибки
|
||||
- фрагмент логов (без паролей)
|
||||
@@ -0,0 +1,53 @@
|
||||
# Тестирование
|
||||
|
||||
Главная цель тестовых режимов — не упереться в лимиты Let’s Encrypt и быстро проверять интеграции.
|
||||
|
||||
## Лимиты Let’s Encrypt
|
||||
|
||||
- production: обычно 5 сертификатов/неделю на домен
|
||||
- при частых ошибках можно быстро исчерпать лимит
|
||||
|
||||
## Варианты тестирования
|
||||
|
||||
### 1) Самоподписанный сертификат (рекомендуется для разработки)
|
||||
|
||||
- `letsencrypt-regru --test-cert`
|
||||
|
||||
Плюсы:
|
||||
|
||||
- мгновенно (1–2 секунды)
|
||||
- без интернета
|
||||
- без DNS
|
||||
- структура файлов совпадает с Let’s Encrypt (`cert.pem`, `fullchain.pem`, …)
|
||||
|
||||
Минусы:
|
||||
|
||||
- браузер не доверяет сертификату
|
||||
|
||||
### 2) Let’s Encrypt staging
|
||||
|
||||
- `letsencrypt-regru --staging`
|
||||
|
||||
Плюсы:
|
||||
|
||||
- полностью реальный процесс ACME
|
||||
- нет лимитов
|
||||
- проверяет DNS-хуки и certbot
|
||||
|
||||
Минусы:
|
||||
|
||||
- staging сертификаты не доверяются браузером
|
||||
|
||||
### 3) Диагностика API и DNS
|
||||
|
||||
- `letsencrypt-regru --test-api -v`
|
||||
- `letsencrypt-regru --test-dns -v`
|
||||
|
||||
Рекомендуется прогонять перед production получением.
|
||||
|
||||
## Переход тест → production
|
||||
|
||||
1) убедиться что всё работает на `--staging` или `--test-cert`
|
||||
2) затем выполнить `--obtain`
|
||||
|
||||
Если ранее создавался тестовый сертификат и вы хотите «чисто» перейти на production, иногда удобно удалить старую папку сертификата для домена в `cert_dir/<domain>/` (аккуратно).
|
||||
@@ -0,0 +1,15 @@
|
||||
# Навигация
|
||||
|
||||
- [Home](Home.md)
|
||||
- [Установка](Installation.md)
|
||||
- [Конфигурация](Configuration.md)
|
||||
- [Команды](Commands.md)
|
||||
- [Алгоритм получения/продления](LetsEncrypt_Workflow.md)
|
||||
- [Интеграция с NPM](Nginx_Proxy_Manager.md)
|
||||
- [Тестирование](Testing.md)
|
||||
- [Проблемы API reg.ru](RegRu_API_Troubleshooting.md)
|
||||
- [Сборка и релизы](Build_and_Release.md)
|
||||
- [Deploy и Secrets](Deploy_Actions_Secrets.md)
|
||||
- [Структура проекта](Project_Structure.md)
|
||||
- [Синхронизация Gitea → GitHub](Gitea_Sync.md)
|
||||
- [Changelog](Changelog.md)
|
||||
Reference in New Issue
Block a user