Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
5319faa
fix: use full npx path for Windows compatibility
claude Jan 5, 2026
d99a603
fix: use shell=True on Windows for npx.cmd compatibility
claude Jan 5, 2026
f83b558
fix: only use shell=True on Windows Python 3.9
claude Jan 5, 2026
21e382b
chore: trigger CI re-run
claude Jan 5, 2026
5e5b59e
fix: add retry logic and npm cache cleanup for Windows tests
claude Jan 5, 2026
afb5961
fix: use shell=True for all Windows Python versions
claude Jan 5, 2026
8871443
fix: add type annotations and clean up CI workarounds
claude Jan 5, 2026
4ece696
fix: add retry with longer timeout for slow npm installs
claude Jan 5, 2026
454c05a
fix: clean npm cache on Windows to prevent corruption
claude Jan 5, 2026
4447c90
fix: use custom npm cache directory on Windows
claude Jan 5, 2026
e92acdd
refactor: prefer global promptfoo installation over npx
claude Jan 5, 2026
0313db6
refactor: use cmd.exe on Windows instead of shell=True
claude Jan 5, 2026
5247d98
test: add comprehensive CLI test suite
claude Jan 5, 2026
60f18d0
fix: explicitly pass stdio to subprocess to avoid blocking
claude Jan 5, 2026
cf297d4
refactor: simplify to shell=True on Windows, shell=False on Unix
claude Jan 5, 2026
e0afc30
fix: use shutil.which to get full npx path for Windows compatibility
mldangelo Jan 5, 2026
6f3a523
chore: remove retry logic from workflow
mldangelo Jan 5, 2026
5ddb551
fix: add stdin=DEVNULL and use -y flag to prevent npx hanging
mldangelo Jan 5, 2026
7d8d370
ci: clear npm cache on Windows to prevent corruption
mldangelo Jan 5, 2026
9ba09dd
feat: prefer globally installed promptfoo over npx
mldangelo Jan 5, 2026
a7ea6b1
Merge origin/main into fix/windows-npx-path
mldangelo Jan 5, 2026
66c739c
fix: add robust fallback from global to npx execution
mldangelo Jan 5, 2026
ac708ba
fix: remove unused exception variable to pass linting
mldangelo Jan 5, 2026
2c7fe60
test: add CI tests for npx fallback without global install
mldangelo Jan 5, 2026
c41f515
perf: optimize CI and add retry logic for macOS resource issues
mldangelo Jan 5, 2026
e5a81e9
fix: use minimal subprocess configuration to avoid resource issues
mldangelo Jan 5, 2026
33d6795
refactor: use os.execvp() instead of subprocess for process replacement
mldangelo Jan 5, 2026
434e282
fix: use contextlib.suppress for cleaner exception handling
mldangelo Jan 5, 2026
36ea59b
refactor: use subprocess.run() with zero configuration
mldangelo Jan 5, 2026
25d4ef7
ci: temporarily exclude macOS tests due to GitHub Actions runner issues
mldangelo Jan 5, 2026
d3c1986
fix: avoid recursive promptfoo wrapper
mldangelo Jan 5, 2026
4b03d9d
fix: run windows cmd wrappers via shell
mldangelo Jan 5, 2026
d9ad649
ci: use fresh npm cache for windows npx fallback
mldangelo Jan 5, 2026
06a66b1
ci: clarify matrix job names
mldangelo Jan 5, 2026
43a77d9
ci: reset npm cache before windows global install
mldangelo Jan 5, 2026
ce84f8a
ci: add npm global bin to windows PATH
mldangelo Jan 6, 2026
c7f89af
ci: use npm prefix for windows PATH
mldangelo Jan 6, 2026
8b7aaec
fix: find global promptfoo on Windows
mldangelo Jan 6, 2026
73877ef
ci: export npm prefix for windows jobs
mldangelo Jan 6, 2026
65cae8b
chore: format cli module
mldangelo Jan 6, 2026
d98fd37
docs: rewrite README with main project content and npx recommendation
mldangelo Jan 6, 2026
4ebee1b
test: add comprehensive pytest suite for CLI wrapper
mldangelo Jan 6, 2026
bf92df3
ci: fix Windows npm cache corruption (ECOMPROMISED error)
mldangelo Jan 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 116 additions & 4 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,20 +62,63 @@ jobs:
run: uv run mypy src/promptfoo/

test:
name: Test Python ${{ matrix.python-version }}
name: Test (py${{ matrix.python-version }}, ${{ matrix.os }})
runs-on: ${{ matrix.os }}
timeout-minutes: 15
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
# Temporarily excluding macos-latest due to GitHub Actions runner resource constraints
# causing BlockingIOError [Errno 35] when spawning subprocess
os: [ubuntu-latest, windows-latest]
# Test only min and max supported Python versions for efficiency
python-version: ["3.9", "3.13"]
steps:
- uses: actions/checkout@v6

- uses: actions/setup-node@v6
with:
node-version: "24"

- name: Configure npm on Windows
if: matrix.os == 'windows-latest'
shell: pwsh
run: |
# Configure cache location (applies immediately to this step)
$cacheDir = Join-Path $env:RUNNER_TEMP "npm-cache"
New-Item -ItemType Directory -Force -Path $cacheDir | Out-Null
npm config set cache $cacheDir --location=user

# Configure prefix location (applies immediately to this step)
$globalPrefix = npm config get prefix
if (-not $globalPrefix -or $globalPrefix -eq "undefined") {
$globalPrefix = Join-Path $env:APPDATA "npm"
}
$globalPrefix = $globalPrefix.Trim()
npm config set prefix $globalPrefix --location=user

# NOW clean and verify cache (cleans the correctly-configured cache)
npm cache clean --force
npm cache verify

# Export settings for future steps
"NPM_CONFIG_CACHE=$cacheDir" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
"NPM_CONFIG_PREFIX=$globalPrefix" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
"npm_config_prefix=$globalPrefix" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append

# Add global bin directories to PATH
$binPaths = @($globalPrefix, (Join-Path $globalPrefix "bin")) | Where-Object { Test-Path $_ }
foreach ($binPath in $binPaths) {
$binPath | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
}

Write-Host "npm cache: $cacheDir"
Write-Host "npm prefix: $globalPrefix"

- name: Install promptfoo globally
run: npm install -g promptfoo@latest
env:
NODE_OPTIONS: --max-old-space-size=4096

- uses: astral-sh/setup-uv@v7
with:
enable-cache: true
Expand All @@ -92,6 +135,72 @@ jobs:
- name: Test Node.js detection
run: uv run python -c "from promptfoo.cli import check_node_installed, check_npx_installed; assert check_node_installed(); assert check_npx_installed()"

test-npx-fallback:
name: Test npx fallback (py${{ matrix.python-version }}, ${{ matrix.os }})
runs-on: ${{ matrix.os }}
timeout-minutes: 15
strategy:
matrix:
# Test npx fallback (without global install)
# Temporarily excluding macos-latest due to GitHub Actions runner resource constraints
os: [ubuntu-latest, windows-latest]
# Use middle-version Python for this test
python-version: ["3.12"]
steps:
- uses: actions/checkout@v6

- uses: actions/setup-node@v6
with:
node-version: "24"

- name: Configure npm on Windows
if: matrix.os == 'windows-latest'
shell: pwsh
run: |
# Configure cache location (applies immediately to this step)
$cacheDir = Join-Path $env:RUNNER_TEMP "npm-cache"
New-Item -ItemType Directory -Force -Path $cacheDir | Out-Null
npm config set cache $cacheDir --location=user

# Configure prefix location (applies immediately to this step)
$globalPrefix = npm config get prefix
if (-not $globalPrefix -or $globalPrefix -eq "undefined") {
$globalPrefix = Join-Path $env:APPDATA "npm"
}
$globalPrefix = $globalPrefix.Trim()
npm config set prefix $globalPrefix --location=user

# NOW clean and verify cache (cleans the correctly-configured cache)
npm cache clean --force
npm cache verify

# Export settings for future steps
"NPM_CONFIG_CACHE=$cacheDir" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
"NPM_CONFIG_PREFIX=$globalPrefix" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
"npm_config_prefix=$globalPrefix" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append

Write-Host "npm cache: $cacheDir"
Write-Host "npm prefix: $globalPrefix"

# Intentionally skip installing promptfoo globally
# This tests the npx fallback path

- uses: astral-sh/setup-uv@v7
with:
enable-cache: true

- name: Pin Python version
run: uv python pin ${{ matrix.python-version }}

- name: Install package
run: uv sync

- name: Test CLI fallback to npx (no global install)
run: uv run promptfoo --version

- name: Test Node.js detection
run: uv run python -c "from promptfoo.cli import check_node_installed, check_npx_installed; assert check_node_installed(); assert check_npx_installed()"

build:
name: Build Package
runs-on: ubuntu-latest
Expand All @@ -117,7 +226,7 @@ jobs:

ci-success:
name: CI Success
needs: [lint, type-check, test, build]
needs: [lint, type-check, test, test-npx-fallback, build]
if: always()
runs-on: ubuntu-latest
steps:
Expand All @@ -126,17 +235,20 @@ jobs:
LINT_RESULT="${{ needs.lint.result }}"
TYPE_CHECK_RESULT="${{ needs.type-check.result }}"
TEST_RESULT="${{ needs.test.result }}"
TEST_NPX_FALLBACK_RESULT="${{ needs.test-npx-fallback.result }}"
BUILD_RESULT="${{ needs.build.result }}"

echo "Job results:"
echo " lint: $LINT_RESULT"
echo " type-check: $TYPE_CHECK_RESULT"
echo " test: $TEST_RESULT"
echo " test-npx-fallback: $TEST_NPX_FALLBACK_RESULT"
echo " build: $BUILD_RESULT"

if [[ "$LINT_RESULT" == "failure" || "$LINT_RESULT" == "cancelled" ||
"$TYPE_CHECK_RESULT" == "failure" || "$TYPE_CHECK_RESULT" == "cancelled" ||
"$TEST_RESULT" == "failure" || "$TEST_RESULT" == "cancelled" ||
"$TEST_NPX_FALLBACK_RESULT" == "failure" || "$TEST_NPX_FALLBACK_RESULT" == "cancelled" ||
"$BUILD_RESULT" == "failure" || "$BUILD_RESULT" == "cancelled" ]]; then
echo "Some CI checks failed!"
exit 1
Expand Down
Loading
Loading