Skip to content

Commit 1655f51

Browse files
committed
Add Linux and macOS build workflows for ARM64 and AMD64 architectures
- Introduced GitHub Actions workflows for building Huntarr on Linux (AMD64 and ARM64) and macOS (ARM64 and Intel). - Each workflow includes steps for setting up the environment, installing dependencies, creating PyInstaller specifications, and building the application. - Added support for generating distribution packages and installers for respective architectures. - Removed outdated macOS installer workflows for ARM and Intel, streamlining the build process. - Enhanced logging and verification steps to ensure successful builds and artifact uploads.
1 parent 95441a4 commit 1655f51

File tree

8 files changed

+1246
-1025
lines changed

8 files changed

+1246
-1025
lines changed
Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
name: Linux Build AMD64
2+
3+
permissions:
4+
contents: write
5+
6+
on:
7+
push:
8+
branches: [ "main", "dev", "linux-*" ]
9+
tags:
10+
- "*"
11+
pull_request:
12+
branches: [ "main", "dev" ]
13+
workflow_dispatch:
14+
15+
jobs:
16+
build:
17+
runs-on: ubuntu-latest
18+
19+
steps:
20+
- name: Checkout code
21+
uses: actions/checkout@v4
22+
with:
23+
fetch-depth: 0
24+
25+
- name: Extract metadata
26+
id: meta
27+
shell: bash
28+
run: |
29+
if [[ "${{ github.ref }}" == refs/tags/* ]]; then
30+
echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
31+
echo "IS_TAG=true" >> $GITHUB_OUTPUT
32+
else
33+
echo "VERSION=$(cat version.txt)" >> $GITHUB_OUTPUT
34+
echo "BRANCH=${GITHUB_REF#refs/heads/}" >> $GITHUB_OUTPUT
35+
echo "IS_TAG=false" >> $GITHUB_OUTPUT
36+
fi
37+
38+
- name: Set up Python
39+
uses: actions/setup-python@v4
40+
with:
41+
python-version: '3.10'
42+
43+
- name: Install system dependencies
44+
run: |
45+
sudo apt-get update
46+
sudo apt-get install -y build-essential
47+
48+
- name: Install Python dependencies
49+
run: |
50+
python -m pip install --upgrade pip
51+
pip install -r requirements.txt
52+
pip install pyinstaller==6.1.0
53+
# Explicitly install apprise and dependencies
54+
pip install apprise==1.6.0
55+
pip install markdown==3.4.3
56+
pip install pyyaml==6.0
57+
58+
- name: Create PyInstaller spec for Linux
59+
run: |
60+
cat > Huntarr-linux.spec << 'EOF'
61+
# -*- mode: python ; coding: utf-8 -*-
62+
from PyInstaller.building.api import PYZ, EXE, COLLECT
63+
from PyInstaller.building.build_main import Analysis
64+
import os
65+
66+
block_cipher = None
67+
68+
datas = [
69+
('frontend', 'frontend'),
70+
('version.txt', '.'),
71+
('README.md', '.'),
72+
('LICENSE', '.'),
73+
('src', 'src'),
74+
]
75+
76+
# Add apprise data files
77+
try:
78+
import apprise
79+
apprise_path = os.path.dirname(apprise.__file__)
80+
apprise_attachment_path = os.path.join(apprise_path, 'attachment')
81+
apprise_plugins_path = os.path.join(apprise_path, 'plugins')
82+
apprise_config_path = os.path.join(apprise_path, 'config')
83+
84+
if os.path.exists(apprise_attachment_path):
85+
datas.append((apprise_attachment_path, 'apprise/attachment'))
86+
if os.path.exists(apprise_plugins_path):
87+
datas.append((apprise_plugins_path, 'apprise/plugins'))
88+
if os.path.exists(apprise_config_path):
89+
datas.append((apprise_config_path, 'apprise/config'))
90+
except ImportError:
91+
print("Warning: apprise not found, skipping apprise data files")
92+
93+
a = Analysis(
94+
['main.py'],
95+
pathex=['.'],
96+
binaries=[],
97+
datas=datas,
98+
hiddenimports=[
99+
'flask', 'flask.json', 'requests', 'waitress', 'bcrypt', 'qrcode', 'PIL',
100+
'pyotp', 'qrcode.image.pil', 'routes', 'main', 'apprise', 'apprise.common',
101+
'apprise.conversion', 'apprise.decorators', 'apprise.locale', 'apprise.logger',
102+
'apprise.manager', 'apprise.utils', 'apprise.URLBase', 'apprise.AppriseAsset',
103+
'apprise.AppriseAttachment', 'apprise.AppriseConfig', 'apprise.cli',
104+
'apprise.config', 'apprise.attachment', 'apprise.plugins', 'markdown', 'yaml', 'cryptography',
105+
],
106+
hookspath=[],
107+
hooksconfig={},
108+
runtime_hooks=[],
109+
excludes=[],
110+
cipher=block_cipher,
111+
noarchive=False,
112+
)
113+
114+
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
115+
116+
exe = EXE(
117+
pyz, a.scripts, a.binaries, a.zipfiles, a.datas, [],
118+
name='huntarr', debug=False, bootloader_ignore_signals=False,
119+
strip=False, upx=True, upx_exclude=[], runtime_tmpdir=None,
120+
console=True, disable_windowed_traceback=False,
121+
)
122+
EOF
123+
124+
- name: Build Linux executable
125+
run: |
126+
# Build Linux executable
127+
python -m PyInstaller Huntarr-linux.spec --clean
128+
129+
# Verify the executable was created
130+
ls -la dist/
131+
file dist/huntarr
132+
133+
# Test that it's executable
134+
chmod +x dist/huntarr
135+
136+
- name: Create distribution package
137+
run: |
138+
# Create distribution directory
139+
mkdir -p dist/huntarr-linux-amd64
140+
141+
# Copy executable
142+
cp dist/huntarr dist/huntarr-linux-amd64/
143+
144+
# Create startup script
145+
cat > dist/huntarr-linux-amd64/start-huntarr.sh << 'EOF'
146+
#!/bin/bash
147+
# Huntarr Linux Startup Script
148+
149+
# Get the directory where this script is located
150+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
151+
cd "$SCRIPT_DIR"
152+
153+
# Set up config directory in user's home
154+
export HUNTARR_CONFIG_DIR="$HOME/.config/huntarr"
155+
mkdir -p "$HUNTARR_CONFIG_DIR"
156+
157+
# Set permissions
158+
chmod -R 755 "$HUNTARR_CONFIG_DIR" 2>/dev/null || true
159+
160+
echo "Starting Huntarr..."
161+
echo "Config directory: $HUNTARR_CONFIG_DIR"
162+
echo "Web interface will be available at: http://localhost:9705"
163+
echo ""
164+
165+
# Start Huntarr
166+
./huntarr
167+
EOF
168+
169+
chmod +x dist/huntarr-linux-amd64/start-huntarr.sh
170+
171+
# Create README
172+
cat > dist/huntarr-linux-amd64/README.txt << 'EOF'
173+
Huntarr Linux AMD64 Distribution
174+
================================
175+
176+
Installation:
177+
1. Extract this archive to your desired location
178+
2. Run: ./start-huntarr.sh
179+
3. Open your browser to: http://localhost:9705
180+
181+
Files:
182+
- huntarr: Main executable
183+
- start-huntarr.sh: Startup script (recommended)
184+
- README.txt: This file
185+
186+
Configuration:
187+
- Config files will be stored in: ~/.config/huntarr/
188+
- Logs are stored in the database (no separate log files)
189+
190+
Requirements:
191+
- Linux AMD64 (x86_64) system
192+
- No additional dependencies required (all bundled)
193+
194+
Support:
195+
- GitHub: https://github.com/plexguide/Huntarr.io
196+
- Documentation: https://plexguide.github.io/Huntarr.io/
197+
EOF
198+
199+
# Copy license and version info
200+
cp LICENSE dist/huntarr-linux-amd64/ 2>/dev/null || true
201+
cp version.txt dist/huntarr-linux-amd64/ 2>/dev/null || true
202+
203+
# Show contents
204+
ls -la dist/huntarr-linux-amd64/
205+
206+
- name: Create archive
207+
run: |
208+
version="${{ steps.meta.outputs.VERSION }}"
209+
210+
if [[ "${{ steps.meta.outputs.IS_TAG }}" == "true" ]]; then
211+
archive_name="Huntarr-${version}-linux-amd64.tar.gz"
212+
else
213+
branch="${{ steps.meta.outputs.BRANCH }}"
214+
branch_safe=$(echo "${branch}" | tr '/' '-')
215+
archive_name="Huntarr-${version}-linux-${branch_safe}-amd64.tar.gz"
216+
fi
217+
218+
cd dist
219+
tar -czf "../${archive_name}" huntarr-linux-amd64/
220+
cd ..
221+
222+
# Verify archive
223+
echo "Created archive: ${archive_name}"
224+
ls -lh "${archive_name}"
225+
tar -tzf "${archive_name}" | head -10
226+
227+
- name: Upload artifacts
228+
uses: actions/upload-artifact@v4
229+
with:
230+
name: huntarr-linux-amd64
231+
path: '*.tar.gz'
232+
retention-days: 30
233+
234+
- name: Upload to release
235+
if: steps.meta.outputs.IS_TAG == 'true'
236+
uses: softprops/action-gh-release@v1
237+
with:
238+
files: '*.tar.gz'
239+
env:
240+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

0 commit comments

Comments
 (0)