Skip to content

Add fix-quarantine.sh script to macOS builds to help users resolve 'd… #4

Add fix-quarantine.sh script to macOS builds to help users resolve 'd…

Add fix-quarantine.sh script to macOS builds to help users resolve 'd… #4

name: Linux Build AMD64
permissions:
contents: write
on:
push:
branches: [ "main", "dev", "linux-*", "test-*" ]
tags:
- "*"
pull_request:
branches: [ "main", "dev" ]
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Extract metadata
id: meta
shell: bash
run: |
if [[ "${{ github.ref }}" == refs/tags/* ]]; then
echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
echo "IS_TAG=true" >> $GITHUB_OUTPUT
else
echo "VERSION=$(cat version.txt)" >> $GITHUB_OUTPUT
echo "BRANCH=${GITHUB_REF#refs/heads/}" >> $GITHUB_OUTPUT
echo "IS_TAG=false" >> $GITHUB_OUTPUT
fi
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.10'
- 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
pip install -r requirements.txt
pip install pyinstaller==6.1.0
# Explicitly install apprise and dependencies
pip install apprise==1.6.0
pip install markdown==3.4.3
pip install pyyaml==6.0
- name: Create PyInstaller spec for Linux
run: |
cat > Huntarr-linux.spec << 'EOF'
# -*- mode: python ; coding: utf-8 -*-
from PyInstaller.building.api import PYZ, EXE, COLLECT
from PyInstaller.building.build_main import Analysis
import os
block_cipher = None
datas = [
('frontend', 'frontend'),
('version.txt', '.'),
('README.md', '.'),
('LICENSE', '.'),
('src', 'src'),
]
# Add apprise data files
try:
import apprise
apprise_path = os.path.dirname(apprise.__file__)
apprise_attachment_path = os.path.join(apprise_path, 'attachment')
apprise_plugins_path = os.path.join(apprise_path, 'plugins')
apprise_config_path = os.path.join(apprise_path, 'config')
if os.path.exists(apprise_attachment_path):
datas.append((apprise_attachment_path, 'apprise/attachment'))
if os.path.exists(apprise_plugins_path):
datas.append((apprise_plugins_path, 'apprise/plugins'))
if os.path.exists(apprise_config_path):
datas.append((apprise_config_path, 'apprise/config'))
except ImportError:
print("Warning: apprise not found, skipping apprise data files")
a = Analysis(
['main.py'],
pathex=['.'],
binaries=[],
datas=datas,
hiddenimports=[
'flask', 'flask.json', 'requests', 'waitress', 'bcrypt', 'qrcode', 'PIL',
'pyotp', 'qrcode.image.pil', 'routes', 'main', 'apprise', 'apprise.common',
'apprise.conversion', 'apprise.decorators', 'apprise.locale', 'apprise.logger',
'apprise.manager', 'apprise.utils', 'apprise.URLBase', 'apprise.AppriseAsset',
'apprise.AppriseAttachment', 'apprise.AppriseConfig', 'apprise.cli',
'apprise.config', 'apprise.attachment', 'apprise.plugins', 'markdown', 'yaml', 'cryptography',
],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
cipher=block_cipher,
noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
exe = EXE(
pyz, a.scripts, a.binaries, a.zipfiles, a.datas, [],
name='huntarr', debug=False, bootloader_ignore_signals=False,
strip=False, upx=True, upx_exclude=[], runtime_tmpdir=None,
console=True, disable_windowed_traceback=False,
)
EOF
- name: Build Linux executable
run: |
# Build Linux executable
python -m PyInstaller Huntarr-linux.spec --clean
# Verify the executable was created
ls -la dist/
file dist/huntarr
# Test that it's executable
chmod +x dist/huntarr
- name: Create distribution package
run: |
# Create distribution directory
mkdir -p dist/huntarr-linux-amd64
# Copy executable
cp dist/huntarr dist/huntarr-linux-amd64/
# Create startup script
cat > dist/huntarr-linux-amd64/start-huntarr.sh << 'EOF'
#!/bin/bash
# Huntarr Linux Startup Script
# Get the directory where this script is located
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"
# Set up config directory in user's home
export HUNTARR_CONFIG_DIR="$HOME/.config/huntarr"
mkdir -p "$HUNTARR_CONFIG_DIR"
# Set permissions
chmod -R 755 "$HUNTARR_CONFIG_DIR" 2>/dev/null || true
echo "Starting Huntarr..."
echo "Config directory: $HUNTARR_CONFIG_DIR"
echo "Web interface will be available at: http://localhost:9705"
echo ""
# Start Huntarr
./huntarr
EOF
chmod +x dist/huntarr-linux-amd64/start-huntarr.sh
# Create README
cat > dist/huntarr-linux-amd64/README.txt << 'EOF'
Huntarr Linux AMD64 Distribution
================================
Installation:
1. Extract this archive to your desired location
2. Run: ./start-huntarr.sh
3. Open your browser to: http://localhost:9705
Files:
- huntarr: Main executable
- start-huntarr.sh: Startup script (recommended)
- README.txt: This file
Configuration:
- Config files will be stored in: ~/.config/huntarr/
- Logs are stored in the database (no separate log files)
Requirements:
- Linux AMD64 (x86_64) system
- No additional dependencies required (all bundled)
Support:
- GitHub: https://github.com/plexguide/Huntarr.io
- Documentation: https://plexguide.github.io/Huntarr.io/
EOF
# Copy license and version info
cp LICENSE dist/huntarr-linux-amd64/ 2>/dev/null || true
cp version.txt dist/huntarr-linux-amd64/ 2>/dev/null || true
# Show contents
ls -la dist/huntarr-linux-amd64/
- name: Create archive
run: |
version="${{ steps.meta.outputs.VERSION }}"
if [[ "${{ steps.meta.outputs.IS_TAG }}" == "true" ]]; then
archive_name="Huntarr-${version}-linux-amd64.tar.gz"
else
branch="${{ steps.meta.outputs.BRANCH }}"
branch_safe=$(echo "${branch}" | tr '/' '-')
archive_name="Huntarr-${version}-linux-${branch_safe}-amd64.tar.gz"
fi
cd dist
tar -czf "../${archive_name}" huntarr-linux-amd64/
cd ..
# Verify archive
echo "Created archive: ${archive_name}"
ls -lh "${archive_name}"
tar -tzf "${archive_name}" | head -10
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: huntarr-linux-amd64
path: '*.tar.gz'
retention-days: 30
- name: Upload to release
if: steps.meta.outputs.IS_TAG == 'true'
uses: softprops/action-gh-release@v1
with:
files: '*.tar.gz'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}