Skip to content

fix(fzd): deduplicate batch inputs before calling fzr #387

fix(fzd): deduplicate batch inputs before calling fzr

fix(fzd): deduplicate batch inputs before calling fzr #387

Workflow file for this run

name: CI
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]
workflow_dispatch:
jobs:
test:
name: Test on ${{ matrix.os }} with Python ${{ matrix.python-version }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
include:
# Test Python 3.14 on Ubuntu only (as it may not be available on all platforms yet)
- os: ubuntu-latest
python-version: '3.14-dev'
exclude:
# Disable Windows + Python 3.9 combination
- os: windows-latest
python-version: '3.9'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
allow-prereleases: true
- name: Install system dependencies (Linux)
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y bc
- name: Install system dependencies (macOS)
if: runner.os == 'macOS'
run: |
brew install bc
- name: Install system dependencies (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
# Install MSYS2 with bash and essential Unix utilities
# fz requires bash and Unix tools (grep, cut, awk, sed, tr) for output parsing
Write-Host "Installing MSYS2 with bash and Unix utilities..."
choco install msys2 -y --params="/NoUpdate"
Write-Host "Installing required MSYS2 packages..."
# Use pacman (MSYS2 package manager) to install packages
# Note: coreutils includes cat, cut, tr, sort, uniq, head, tail
$env:MSYSTEM = "MSYS"
# Update package database
C:\msys64\usr\bin\bash.exe -lc "pacman -Sy --noconfirm"
# Install required packages
C:\msys64\usr\bin\bash.exe -lc "pacman -S --noconfirm bash grep gawk sed bc coreutils"
Write-Host "✓ MSYS2 installation complete with all required packages"
# Add MSYS2 bin directory to PATH immediately to ensure it's found first
$env:PATH = "C:\msys64\usr\bin;$env:PATH"
echo "C:\msys64\usr\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
Write-Host "✓ MSYS2 added to PATH (prepended to ensure priority)"
- name: List installed MSYS2 utilities (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
Write-Host "Listing executables in C:\msys64\usr\bin..."
Write-Host ""
# List all .exe files in msys64/usr/bin
$binFiles = Get-ChildItem -Path "C:\msys64\usr\bin" -Filter "*.exe" | Select-Object -ExpandProperty Name
# Check for key utilities we need
$keyUtilities = @("bash.exe", "grep.exe", "cut.exe", "awk.exe", "gawk.exe", "sed.exe", "tr.exe", "cat.exe", "sort.exe", "uniq.exe", "head.exe", "tail.exe")
Write-Host "Key utilities required by fz:"
foreach ($util in $keyUtilities) {
if ($binFiles -contains $util) {
Write-Host " ✓ $util"
} else {
Write-Host " ✗ $util (NOT FOUND)"
}
}
Write-Host ""
Write-Host "Total executables installed: $($binFiles.Count)"
Write-Host ""
Write-Host "Sample of other utilities available:"
$binFiles | Where-Object { $_ -notin $keyUtilities } | Select-Object -First 20 | ForEach-Object { Write-Host " - $_" }
Write-Host ""
Write-Host "Verifying MSYS2 bash is in PATH:"
$bashCmd = Get-Command bash -ErrorAction SilentlyContinue
if ($bashCmd) {
Write-Host " ✓ bash found at: $($bashCmd.Source)"
if ($bashCmd.Source -like "*msys64*") {
Write-Host " ✓ Using MSYS2 bash (correct)"
} else {
Write-Host " ⚠ WARNING: Not using MSYS2 bash (found at $($bashCmd.Source))"
}
} else {
Write-Host " ✗ bash not found in PATH"
}
- name: Verify Unix utilities (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
# Verify bash and essential Unix utilities are available
Write-Host "Verifying Unix utilities..."
# First confirm we're using MSYS2 bash
$bashPath = (Get-Command bash).Source
Write-Host "Using bash at: $bashPath"
if ($bashPath -notlike "*msys64*") {
Write-Host "ERROR: Not using MSYS2 bash! Found: $bashPath"
exit 1
}
Write-Host "✓ Confirmed MSYS2 bash"
Write-Host ""
$utilities = @("bash", "grep", "cut", "awk", "sed", "tr", "sort", "uniq", "head", "tail")
$allFound = $true
foreach ($util in $utilities) {
try {
& $util --version 2>&1 | Out-Null
if ($LASTEXITCODE -eq 0 -or $LASTEXITCODE -eq $null) {
Write-Host " ✓ $util"
} else {
Write-Host " ✗ $util (exit code: $LASTEXITCODE)"
$allFound = $false
}
} catch {
Write-Host " ✗ $util (not found)"
$allFound = $false
}
}
if (-not $allFound) {
Write-Host "`nERROR: Some Unix utilities are missing"
exit 1
}
Write-Host "`n✓ All Unix utilities are available and working"
- name: Install R and dependencies (Linux)
if: runner.os == 'Linux'
run: |
sudo apt-get install -y \
r-base \
r-base-dev \
libpcre2-dev \
libdeflate-dev \
libzstd-dev \
liblzma-dev \
libtirpc-dev \
libbz2-dev \
libcurl4-openssl-dev \
libreadline-dev
- name: Install R (macOS)
if: runner.os == 'macOS'
run: |
brew install r
- name: Install R (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
choco install r.project -y
- name: Install Python dependencies
run: |
python -m pip install --upgrade pip
pip install -e .
pip install pandas numpy scipy matplotlib
pip install pytest pytest-cov
pip install getpass4
pip install rpy2
- name: Setup SSH server (Linux only)
if: runner.os == 'Linux'
run: |
sudo apt-get install -y openssh-server
sudo systemctl enable ssh
sudo systemctl start ssh
echo "SSH server installed and started"
echo "Configure ssh key auth"
sudo sed -i 's/PasswordAuthentication yes/PasswordAuthentication no/g' /etc/ssh/sshd_config
sudo sed -i 's/#PubkeyAuthentication no/PubkeyAuthentication yes/g' /etc/ssh/sshd_config
sudo sed -i 's/#ChallengeResponseAuthentication yes/ChallengeResponseAuthentication no/g' /etc/ssh/sshd_config
echo "Restart sshd service"
sudo systemctl restart sshd
- name: Start SSH agent (Linux only)
if: runner.os == 'Linux'
run: |
echo "Starting SSH agent..."
eval "$(ssh-agent -s)"
echo "SSH_AUTH_SOCK=$SSH_AUTH_SOCK" >> $GITHUB_ENV
echo "SSH_AGENT_PID=$SSH_AGENT_PID" >> $GITHUB_ENV
echo "✓ SSH agent started"
- name: Run tests (Windows)
if: runner.os == 'Windows'
run: |
pytest tests/ -v --tb=short -x --ignore=tests/test_examples_advanced.py --ignore=tests/test_examples_modelica.py --ignore=tests/test_examples_perfectgaz.py --ignore=tests/test_examples_runner.py --ignore=tests/test_examples_telemac.py --ignore=tests/test_interrupt_handling.py --ignore=tests/test_ssh_availability_check.py --ignore=tests/test_ssh_directory_uniqueness.py --ignore=tests/test_ssh_localhost.py --ignore=tests/test_ssh_many_cases.py --ignore=tests/test_ssh_perfectgaz.py --ignore=tests/test_funz_integration.py --ignore=tests/test_funz_protocol.py
- name: Run tests (macOS)
if: runner.os == 'macOS'
run: |
pytest tests/ -v --tb=short -x --ignore=tests/test_examples_advanced.py --ignore=tests/test_examples_modelica.py --ignore=tests/test_examples_perfectgaz.py --ignore=tests/test_examples_runner.py --ignore=tests/test_examples_telemac.py --ignore=tests/test_ssh_availability_check.py --ignore=tests/test_ssh_directory_uniqueness.py --ignore=tests/test_ssh_localhost.py --ignore=tests/test_ssh_many_cases.py --ignore=tests/test_ssh_perfectgaz.py --ignore=tests/test_funz_integration.py --ignore=tests/test_funz_protocol.py
- name: Run tests (Linux)
if: runner.os == 'Linux'
run: |
pytest tests/ --full-trace -v --tb=long -x --ignore=tests/test_examples_advanced.py --ignore=tests/test_examples_modelica.py --ignore=tests/test_examples_perfectgaz.py --ignore=tests/test_examples_runner.py --ignore=tests/test_examples_telemac.py --ignore=tests/test_funz_integration.py --ignore=tests/test_funz_protocol.py
- name: Run tests with coverage (Ubuntu only)
if: runner.os == 'Linux' && matrix.python-version == '3.11'
run: |
pytest tests/ --cov=fz --cov-report=xml --cov-report=term -v --ignore=tests/test_examples_advanced.py --ignore=tests/test_examples_modelica.py --ignore=tests/test_examples_perfectgaz.py --ignore=tests/test_examples_runner.py --ignore=tests/test_examples_telemac.py --ignore=tests/test_funz_integration.py --ignore=tests/test_funz_protocol.py
- name: Upload coverage to Codecov
if: runner.os == 'Linux' && matrix.python-version == '3.11'
uses: codecov/codecov-action@v4
with:
file: ./coverage.xml
flags: unittests
name: codecov-umbrella
fail_ci_if_error: false
build-wheels:
name: Build wheels on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
needs: test
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install build dependencies
run: |
python -m pip install --upgrade pip
pip install build wheel
- name: Build wheel
run: |
python -m build --wheel --outdir dist/
- name: Upload wheel artifacts
uses: actions/upload-artifact@v4
with:
name: wheels-${{ matrix.os }}
path: dist/*.whl
retention-days: 30
build-sdist:
name: Build source distribution
runs-on: ubuntu-latest
needs: test
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install build dependencies
run: |
python -m pip install --upgrade pip
pip install build
- name: Build sdist
run: |
python -m build --sdist --outdir dist/
- name: Upload sdist artifact
uses: actions/upload-artifact@v4
with:
name: sdist
path: dist/*.tar.gz
retention-days: 30
lint:
name: Lint and format check
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install linting tools
run: |
python -m pip install --upgrade pip
pip install flake8 black
- name: Check code formatting with black
run: |
black --check fz/ tests/ || true
- name: Lint with flake8
run: |
# Stop the build if there are Python syntax errors or undefined names
flake8 fz/ --count --select=E9,F63,F7,F82 --show-source --statistics
# Exit-zero treats all errors as warnings
flake8 fz/ --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics || true