Skip to content
39 changes: 39 additions & 0 deletions .github/scripts/install-ffmpeg-linux.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/bin/bash
# Script to install ffmpeg on Linux with timeout and retry
# Usage: install-ffmpeg-linux.sh

set -e

TIMEOUT_SECONDS=60
URL="https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz"
PATTERN="ffmpeg-*-amd64-static"

echo "Downloading and installing ffmpeg..."

# Try to download and install ffmpeg with timeout
if timeout "$TIMEOUT_SECONDS" wget -q "$URL" && \
timeout "$TIMEOUT_SECONDS" tar -xf ffmpeg-release-amd64-static.tar.xz; then
sudo mv ${PATTERN}/ffmpeg /usr/local/bin/
sudo mv ${PATTERN}/ffprobe /usr/local/bin/
rm -rf ${PATTERN}*
echo "ffmpeg installed successfully on first attempt"
else
echo "First attempt failed or timed out, retrying..."
# Clean up any partial downloads
rm -rf ${PATTERN}* 2>/dev/null || true
# Retry with timeout
if timeout "$TIMEOUT_SECONDS" wget -q "$URL" && \
timeout "$TIMEOUT_SECONDS" tar -xf ffmpeg-release-amd64-static.tar.xz; then
sudo mv ${PATTERN}/ffmpeg /usr/local/bin/
sudo mv ${PATTERN}/ffprobe /usr/local/bin/
rm -rf ${PATTERN}*
echo "ffmpeg installed successfully on second attempt"
else
echo "ffmpeg installation failed after 2 attempts"
exit 1
fi
fi

# Verify installation
ffmpeg -version | head -n1
echo "ffmpeg installation complete"
76 changes: 76 additions & 0 deletions .github/scripts/install-ffmpeg-macos.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#!/bin/bash
# Script to install ffmpeg on macOS with timeout and retry
# Usage: install-ffmpeg-macos.sh <target_dir>
# Example: install-ffmpeg-macos.sh lib/mac

set -e

TARGET_DIR="${1:-lib/mac}"
TIMEOUT_SECONDS=60
URL="https://evermeet.cx/ffmpeg/getrelease/ffmpeg/zip"

echo "Downloading and installing ffmpeg for macOS..."

# Function to run command with timeout using Python
# Only used internally with controlled commands (no user input)
run_with_timeout() {
local timeout=$1
shift
# Pass command as separate arguments to avoid injection issues
python3 -c '
import subprocess
import sys

timeout = int(sys.argv[1])
cmd = sys.argv[2:]

try:
result = subprocess.run(
cmd,
timeout=timeout,
capture_output=False
)
sys.exit(result.returncode)
except subprocess.TimeoutExpired:
sys.exit(124)
' "$timeout" "$@"
}

# Function to attempt download and extraction
attempt_install() {
local TEMP_DIR=$(mktemp -d)
cd "$TEMP_DIR"

if run_with_timeout "$TIMEOUT_SECONDS" wget -q "$URL" -O ffmpeg.zip && \
run_with_timeout "$TIMEOUT_SECONDS" unzip -q ffmpeg.zip; then
chmod +x ffmpeg
mv ffmpeg "$GITHUB_WORKSPACE/$TARGET_DIR/ffmpeg"
cd "$GITHUB_WORKSPACE"
chmod -R u+w "$TEMP_DIR" || true
rm -rf "$TEMP_DIR"
return 0
else
cd "$GITHUB_WORKSPACE"
chmod -R u+w "$TEMP_DIR" || true
rm -rf "$TEMP_DIR"
return 1
fi
}

# First attempt
if attempt_install; then
echo "ffmpeg downloaded successfully on first attempt"
else
echo "First attempt failed or timed out, retrying..."
# Retry
if attempt_install; then
echo "ffmpeg downloaded successfully on second attempt"
else
echo "ffmpeg installation failed after 2 attempts"
exit 1
fi
fi

# Verify installation
"$GITHUB_WORKSPACE/$TARGET_DIR/ffmpeg" -version | head -n1
echo "ffmpeg installation complete"
7 changes: 1 addition & 6 deletions .github/workflows/copilot-setup-steps.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,7 @@ jobs:
tttool --help || { echo "Error: tttool installation failed"; exit 1; }

- name: Install ffmpeg (static build)
run: |
wget -q https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz
tar -xf ffmpeg-release-amd64-static.tar.xz
sudo mv ffmpeg-*-amd64-static/ffmpeg /usr/local/bin/
sudo mv ffmpeg-*-amd64-static/ffprobe /usr/local/bin/
rm -rf ffmpeg-*-amd64-static*
run: .github/scripts/install-ffmpeg-linux.sh

- name: Install Python dependencies
run: |
Expand Down
7 changes: 1 addition & 6 deletions .github/workflows/e2e-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,7 @@ jobs:
tttool --help || { echo "Error: tttool installation failed"; exit 1; }

- name: Install ffmpeg (static build)
run: |
wget -q https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz
tar -xf ffmpeg-release-amd64-static.tar.xz
sudo mv ffmpeg-*-amd64-static/ffmpeg /usr/local/bin/
sudo mv ffmpeg-*-amd64-static/ffprobe /usr/local/bin/
rm -rf ffmpeg-*-amd64-static*
run: .github/scripts/install-ffmpeg-linux.sh

- name: Install Python dependencies
run: |
Expand Down
106 changes: 70 additions & 36 deletions .github/workflows/release-executables.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,21 +67,76 @@ jobs:
run: |
Write-Host "Downloading ffmpeg for Windows"

# Download ffmpeg to temp directory
$tempDir = New-Item -ItemType Directory -Path (Join-Path $env:TEMP "ffmpeg-temp-$(Get-Random)")
$url = "https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-essentials.zip"
$zipPath = Join-Path $tempDir "ffmpeg.zip"
Invoke-WebRequest -Uri $url -OutFile $zipPath

# Extract to temp directory
Expand-Archive -Path $zipPath -DestinationPath $tempDir -Force

# Find and move ffmpeg.exe
$ffmpegDir = Get-ChildItem -Path $tempDir -Directory -Filter "ffmpeg-*" | Select-Object -First 1
Move-Item -Path (Join-Path $ffmpegDir.FullName "bin/ffmpeg.exe") -Destination lib/win/ffmpeg.exe -Force
# Function to download and extract ffmpeg with timeout
function Install-Ffmpeg {
param([int]$TimeoutSeconds = 60)

$tempDir = New-Item -ItemType Directory -Path (Join-Path $env:TEMP "ffmpeg-temp-$(Get-Random)")
$url = "https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-essentials.zip"
$zipPath = Join-Path $tempDir "ffmpeg.zip"

try {
# Download with timeout
$job = Start-Job -ScriptBlock {
param($url, $zipPath)
Invoke-WebRequest -Uri $url -OutFile $zipPath
} -ArgumentList $url, $zipPath

if (Wait-Job -Job $job -Timeout $TimeoutSeconds) {
Receive-Job -Job $job
Remove-Job -Job $job -Force

# Extract with timeout
$extractJob = Start-Job -ScriptBlock {
param($zipPath, $tempDir)
Expand-Archive -Path $zipPath -DestinationPath $tempDir -Force
} -ArgumentList $zipPath, $tempDir

if (Wait-Job -Job $extractJob -Timeout $TimeoutSeconds) {
Receive-Job -Job $extractJob
Remove-Job -Job $extractJob -Force

# Find and move ffmpeg.exe
$ffmpegDir = Get-ChildItem -Path $tempDir -Directory -Filter "ffmpeg-*" | Select-Object -First 1
Move-Item -Path (Join-Path $ffmpegDir.FullName "bin/ffmpeg.exe") -Destination lib/win/ffmpeg.exe -Force
return $true
} else {
Stop-Job -Job $extractJob
Remove-Job -Job $extractJob -Force
return $false
}
} else {
Stop-Job -Job $job
Remove-Job -Job $job -Force
return $false
}
} finally {
# Cleanup temp directory
if (Test-Path $tempDir) {
Remove-Item -Recurse -Force $tempDir -ErrorAction SilentlyContinue
}
}
}

# Cleanup temp directory
Remove-Item -Recurse -Force $tempDir
# Try first attempt
Write-Host "Attempting to download ffmpeg (attempt 1)..."
if (Install-Ffmpeg -TimeoutSeconds 60) {
Write-Host "ffmpeg installed successfully on first attempt"
} else {
Write-Host "First attempt failed or timed out, retrying..."
# Clean up any stale temp directories (Install-Ffmpeg cleans up its own temp dir in finally block)
Get-ChildItem -Path $env:TEMP -Directory -Filter "ffmpeg-temp-*" -ErrorAction SilentlyContinue |
Remove-Item -Recurse -Force -ErrorAction SilentlyContinue

# Retry
Write-Host "Attempting to download ffmpeg (attempt 2)..."
if (Install-Ffmpeg -TimeoutSeconds 60) {
Write-Host "ffmpeg installed successfully on second attempt"
} else {
Write-Host "ffmpeg installation failed after 2 attempts"
exit 1
}
}

# Verify
lib/win/ffmpeg.exe -version
Expand Down Expand Up @@ -171,28 +226,7 @@ jobs:
}

- name: Download ffmpeg for macOS
run: |
echo "Downloading ffmpeg for macOS"

# Create temp directory for extraction
TEMP_DIR=$(mktemp -d)
cd "$TEMP_DIR"

# Download ffmpeg static build for macOS
wget -q "https://evermeet.cx/ffmpeg/getrelease/ffmpeg/zip" -O ffmpeg.zip
unzip -q ffmpeg.zip

# Move binary to lib/mac
chmod +x ffmpeg
mv ffmpeg "$GITHUB_WORKSPACE/lib/mac/ffmpeg"

# Cleanup temp directory - change permissions first to ensure deletion succeeds
cd "$GITHUB_WORKSPACE"
chmod -R u+w "$TEMP_DIR" || true
rm -rf "$TEMP_DIR"

# Verify
lib/mac/ffmpeg -version
run: .github/scripts/install-ffmpeg-macos.sh lib/mac

- name: Build macOS executable with PyInstaller
run: |
Expand Down
19 changes: 17 additions & 2 deletions setup_e2e_environment.sh
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,25 @@ print_success "tttool installed successfully"
print_step "Step 4: Installing ffmpeg"
if ! command -v ffmpeg &> /dev/null; then
echo "=> Installing ffmpeg..." >> "$INSTALL_LOG"
sudo apt-get install -y ffmpeg >> "$INSTALL_LOG" 2>&1
# Try with 60 second timeout
if timeout 60 sudo apt-get install -y ffmpeg >> "$INSTALL_LOG" 2>&1; then
print_success "ffmpeg installed on first attempt"
else
echo "=> First attempt failed or timed out, retrying..." >> "$INSTALL_LOG"
echo "Retrying ffmpeg installation (timeout or failure on first attempt)..."
# Retry with 60 second timeout
if timeout 60 sudo apt-get install -y ffmpeg >> "$INSTALL_LOG" 2>&1; then
print_success "ffmpeg installed on second attempt"
else
print_error "ffmpeg installation failed after 2 attempts"
echo "ffmpeg installation failed after 2 attempts" >> "$INSTALL_LOG"
exit 1
fi
fi
else
print_success "ffmpeg already installed"
fi
ffmpeg -version | head -n1
print_success "ffmpeg installed"

print_step "Step 5: Installing Python dependencies"
PIP_LOG="/tmp/pip_install.log"
Expand Down