feat: Remove deprecated SSL private key and add .gitkeep for certs di… #48
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Build and Release | |
on: | |
push: | |
tags: | |
- "*" | |
branches: | |
- "main" | |
pull_request: | |
branches: | |
- "main" | |
jobs: | |
build-windows: | |
if: startsWith(github.ref, 'refs/tags/') | |
runs-on: windows-latest | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Setup Node.js | |
uses: actions/setup-node@v3 | |
with: | |
node-version: "18" | |
- name: Install Python | |
uses: actions/setup-python@v4 | |
with: | |
python-version: "3.11" | |
architecture: "x64" | |
- name: Setup Python and venv | |
run: | | |
python -m venv venv | |
.\venv\Scripts\activate | |
python -m pip install --upgrade pip | |
python -m pip install wheel pyinstaller | |
pip install -r requirements.txt | |
- name: Create .env file for backend | |
run: | | |
echo "JWT_SECRET=${{ secrets.JWT_SECRET }}" >> backend/.env | |
- name: Extract tag name | |
id: get_version | |
run: echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV | |
- name: Create .env file for frontend | |
run: | | |
echo "NEXT_PUBLIC_REACT_APP_VERSION=${{ env.VERSION }}" >> frontend/.env | |
- name: Build the Frontend | |
shell: pwsh | |
run: | | |
$ErrorActionPreference = "Stop" | |
Write-Host "=== Starting build process ===" | |
# Build Next.js app | |
Write-Host "Building Next.js app..." | |
cd frontend | |
npm install | |
npm run build | |
Write-Host "=== Preparing static files ===" | |
# Clean and create static directory | |
if (Test-Path -Path "../backend/static") { | |
Remove-Item -Recurse -Force ../backend/static | |
} | |
New-Item -ItemType Directory -Force -Path ../backend/static | |
# Copy the exported Next.js app to Flask static directory | |
Write-Host "Copying files to static directory..." | |
Copy-Item -Recurse -Force out/* ../backend/static/ | |
# Verify the copy | |
Write-Host "=== Verifying static files ===" | |
if (-not (Test-Path -Path "../backend/static/index.html")) { | |
Write-Host "ERROR: index.html not found in static directory!" | |
exit 1 | |
} | |
Write-Host "Contents of static directory:" | |
Get-ChildItem -Path ../backend/static | |
Write-Host "=== Build complete ===" | |
- name: Build Windows Executable | |
run: | | |
.\venv\Scripts\activate | |
pyinstaller --noconfirm --onefile --uac-admin --icon "frontend/public/favicon.ico" ` | |
--paths "venv/Lib/site-packages" ` | |
--add-data "backend;." ` | |
--add-data "backend/.env;." ` | |
--add-data "frontend/out;static" ` | |
--add-data "venv/Lib/site-packages/fake_useragent/data;fake_useragent/data" ` | |
--add-data "venv/Lib/site-packages/fake_useragent;fake_useragent" ` | |
--add-data "venv/Lib/site-packages/streamlink;streamlink" ` | |
--add-data "venv/Lib/site-packages/websocket;websocket" ` | |
--add-data "venv/Lib/site-packages/cffi;cffi" ` | |
--add-data "venv/Lib/site-packages/Crypto;Crypto" ` | |
--add-data "venv/Lib/site-packages/psutil;psutil" ` | |
--collect-data fake_useragent ` | |
--collect-submodules streamlink ` | |
--collect-submodules websocket ` | |
--collect-submodules cffi ` | |
--collect-submodules Crypto ` | |
--hidden-import rich ` | |
--hidden-import dotenv ` | |
--hidden-import trio ` | |
"backend/main.py" ` | |
--name "KickViewerBOT.exe" | |
- name: Upload artifact | |
uses: actions/upload-artifact@v4 | |
with: | |
name: windows-build | |
path: dist/KickViewerBOT.exe | |
build-macos: | |
runs-on: macos-latest | |
if: startsWith(github.ref, 'refs/tags/') | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Setup Node.js | |
uses: actions/setup-node@v3 | |
with: | |
node-version: "18" | |
- name: Install Python | |
uses: actions/setup-python@v4 | |
with: | |
python-version: "3.11" | |
- name: Setup Python and venv | |
run: | | |
python -m venv venv | |
source venv/bin/activate | |
python -m pip install --upgrade pip | |
python -m pip install pyinstaller | |
pip install -r requirements.txt | |
- name: Create .env file for backend | |
run: | | |
echo "JWT_SECRET=${{ secrets.JWT_SECRET }}" >> backend/.env | |
- name: Extract tag name | |
id: get_version | |
run: echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV | |
- name: Create .env file for frontend | |
run: | | |
echo "NEXT_PUBLIC_REACT_APP_VERSION=${{ env.VERSION }}" >> frontend/.env | |
- name: Build the Frontend | |
run: | | |
set -e | |
echo "=== Starting build process ===" | |
# Build Next.js app | |
echo "Building Next.js app..." | |
cd frontend | |
npm install | |
npm run build | |
echo "=== Preparing static files ===" | |
# Clean and create static directory | |
rm -rf ../backend/static | |
mkdir -p ../backend/static | |
# Copy the exported Next.js app to Flask static directory | |
echo "Copying files to static directory..." | |
cp -rv out/* ../backend/static/ | |
# Ensure proper permissions | |
echo "Setting permissions..." | |
chmod -R 755 ../backend/static | |
find ../backend/static -type f -exec chmod 644 {} \; | |
find ../backend/static -type d -exec chmod 755 {} \; | |
# Verify the copy | |
echo "=== Verifying static files ===" | |
if [ ! -f "../backend/static/index.html" ]; then | |
echo "ERROR: index.html not found in static directory!" | |
exit 1 | |
fi | |
echo "Contents of static directory:" | |
ls -la ../backend/static | |
echo "=== Build complete ===" | |
- name: Build MacOS App | |
run: | | |
source venv/bin/activate | |
pyinstaller --noconfirm --onefile --icon "frontend/public/favicon.ico" \ | |
--paths "venv/lib/python3.11/site-packages" \ | |
--add-data "backend:." \ | |
--add-data "backend/.env:." \ | |
--add-data "frontend/out:static" \ | |
--add-data "venv/lib/python3.11/site-packages/fake_useragent/data:fake_useragent/data" \ | |
--add-data "venv/lib/python3.11/site-packages/fake_useragent:fake_useragent" \ | |
--add-data "venv/lib/python3.11/site-packages/streamlink:streamlink" \ | |
--add-data "venv/lib/python3.11/site-packages/websocket:websocket" \ | |
--add-data "venv/lib/python3.11/site-packages/cffi:cffi" \ | |
--add-data "venv/lib/python3.11/site-packages/Crypto:Crypto" \ | |
--add-data "venv/lib/python3.11/site-packages/psutil:psutil" \ | |
--collect-data fake_useragent \ | |
--collect-submodules streamlink \ | |
--collect-submodules websocket \ | |
--collect-submodules cffi \ | |
--collect-submodules Crypto \ | |
--hidden-import rich \ | |
--hidden-import dotenv \ | |
--hidden-import trio \ | |
--hidden-import resource \ | |
"backend/main.py" \ | |
--name "KickViewerBOT" | |
- name: zip the app | |
run: | | |
cd dist | |
zip -r KickViewerBOT-MacOS.zip KickViewerBOT | |
- name: Upload artifact | |
uses: actions/upload-artifact@v4 | |
with: | |
name: macos-build | |
path: dist/KickViewerBOT-MacOS.zip | |
create-release: | |
needs: [build-windows, build-macos] | |
runs-on: ubuntu-latest | |
if: startsWith(github.ref, 'refs/tags/') | |
steps: | |
- name: Extract tag name | |
id: get_version | |
run: echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT | |
- name: Download all artifacts | |
uses: actions/download-artifact@v4 | |
with: | |
path: artifacts | |
- name: Create Release | |
id: create_release | |
uses: actions/create-release@v1 | |
env: | |
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }} | |
with: | |
tag_name: ${{ github.ref }} | |
release_name: Release ${{ steps.get_version.outputs.VERSION }} | |
body: | | |
# 🚀 KickViewerBOT Release Notes V${{ steps.get_version.outputs.VERSION }} | |
## 🔒 SSL Certificate Management - Major Fix | |
### ✅ **Fixed Critical SSL Error** | |
- **Resolved**: `ssl.SSLError: [SSL: SSLV3_ALERT_CERTIFICATE_UNKNOWN]` that was preventing HTTPS server startup | |
- **Root Cause**: Expired SSL certificates (expired May 18, 2025) and mismatched certificate/private key pairs | |
### 🛠️ **Enhanced Certificate Management** | |
- **Auto-Download**: Now automatically downloads both certificate AND private key from secure API endpoints | |
- **Validation**: SSL certificate/key pair validation before server startup | |
- **Backup System**: Automatic backup creation before certificate updates | |
- **Auto-Restore**: Fallback to backup certificates if new ones fail validation | |
### 🔄 **Improved Resilience** | |
- **Smart Fallback**: Automatically falls back to HTTP mode if HTTPS certificates fail | |
- **Self-Healing**: Auto-renewal of expired certificates with random delays to prevent API overload | |
- **Better Logging**: Enhanced error reporting for SSL certificate debugging | |
- **Graceful Degradation**: Application continues running even with certificate issues | |
### 📋 **Technical Improvements** | |
- Updated `fetch_certificate()` function to handle both cert and key downloads | |
- Enhanced `ensure_valid_certificates()` with better error handling | |
- Added SSL context validation before server startup | |
- Improved certificate expiry checking with OpenSSL integration | |
### 🎯 **Results** | |
- ✅ **HTTPS Server**: Now runs reliably on port 443 with valid certificates | |
- ✅ **Zero Downtime**: No more SSL-related crashes | |
- ✅ **Auto-Recovery**: Handles certificate renewals without manual intervention | |
- ✅ **Future-Proof**: Ready for automatic certificate updates | |
## 🎉 Additional Features | |
- Enhanced server stability and error handling | |
- Improved logging for better troubleshooting | |
**This release ensures your KickViewerBOT runs with secure HTTPS and handles certificate management automatically!** 🔐✨ | |
draft: false | |
prerelease: false | |
- name: Upload Windows Release Asset | |
uses: actions/upload-release-asset@v1 | |
env: | |
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }} | |
with: | |
upload_url: ${{ steps.create_release.outputs.upload_url }} | |
asset_path: ./artifacts/windows-build/KickViewerBOT.exe | |
asset_name: KickViewerBOT-Windows.exe | |
asset_content_type: application/octet-stream | |
- name: Upload MacOS Release Asset | |
uses: actions/upload-release-asset@v1 | |
env: | |
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }} | |
with: | |
upload_url: ${{ steps.create_release.outputs.upload_url }} | |
asset_path: ./artifacts/macos-build/KickViewerBOT-MacOS.zip | |
asset_name: KickViewerBOT-MacOS.zip | |
asset_content_type: application/zip |