Skip to content

feat: Enhance KickViewerBOT packaging with additional dependencies an… #66

feat: Enhance KickViewerBOT packaging with additional dependencies an…

feat: Enhance KickViewerBOT packaging with additional dependencies an… #66

Workflow file for this run

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
shell: pwsh
run: |
$version = "${env:GITHUB_REF}" -replace 'refs/tags/', ''
echo "VERSION=$version" >> $env:GITHUB_OUTPUT
- name: Create .env file for frontend
run: |
echo NEXT_PUBLIC_REACT_APP_VERSION=${{ steps.get_version.outputs.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/websockets;websockets" `
--add-data "venv/Lib/site-packages/tls_client;tls_client" `
--add-data "venv/Lib/site-packages/tls_client/dependencies;tls_client/dependencies" `
--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 websockets `
--collect-submodules tls_client `
--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_OUTPUT
- name: Create .env file for frontend
run: |
echo "NEXT_PUBLIC_REACT_APP_VERSION=${{ steps.get_version.outputs.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 KickViewerBOT-macOS.spec
- 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 }}
## Major Fixes
- **WebSocket & Browser Fingerprint Fix:**
The bot now uses the `tls_client` library with a Chrome 120 fingerprint for all HTTP and WebSocket requests to Kick.com. This bypasses the new anti-bot protections and resolves the 403 errors, even when using premium proxies.
- **PyInstaller Build Improvements:**
- The build process now includes all native binaries required by `tls_client` (DLL, SO, DYLIB files) for both Windows and macOS.
- The PyInstaller `.spec` files have been updated to use the correct user `site-packages` path, ensuring all dependencies (like `fake_useragent`, `websockets`, etc.) are bundled correctly.
- The GitHub Actions pipeline was updated to use these `.spec` files for reliable cross-platform builds.
- **Dependency Updates:**
- Added `tls_client` and `websockets>=12.0` to requirements.
- Ensured all required Python packages are installed and included in the build.
## Special Thanks
Big thanks to everyone who contributed to [Issue #14](https://github.com/H1B0B0/Kick-Viewerbot/issues/14) and helped with the fix, especially:
- [@JUSTRobot-hub](https://github.com/JUSTRobot-hub)
- [@0xfiraterdem](https://github.com/0xfiraterdem)
- [@SLAYER-CODE](https://github.com/SLAYER-CODE)
- [@kademerchant](https://github.com/kademerchant)
- [@pecatum](https://github.com/pecatum)
- [@malek10xdev](https://github.com/malek10xdev)
Your feedback, code, and suggestions were crucial to restoring full functionality. 🙏
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