diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 006a98ca6..61d61330c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -740,6 +740,8 @@ jobs: name: "smoke test | linux" runs-on: ubuntu-latest steps: + - uses: actions/checkout@v4 + - name: "Download binary" uses: actions/download-artifact@cc203385981b70ca67e1cc392babf9cc229d5806 # v4.1.9 with: @@ -752,9 +754,10 @@ jobs: - name: "Smoke test" run: | - ./uv venv -v - ./uv pip install ruff -v - ./uvx -v ruff --version + ./uv run scripts/smoke-test + + - name: "Test shell completions" + run: | eval "$(./uv generate-shell-completion bash)" eval "$(./uvx --generate-shell-completion bash)" @@ -779,14 +782,7 @@ jobs: - name: "Smoke test" run: | - # Overwrite the 3.13.0 pin from the project, there are not functional - # musl distributions for it - ./uv python pin 3.13 - ./uv venv -v - ./uv pip install ruff -v - ./uvx -v ruff --version - ./uv pip install numpy -v - ./uv run python -c "import numpy; print(numpy.__version__)" + ./uv run scripts/smoke-test smoke-test-macos: timeout-minutes: 10 @@ -794,6 +790,8 @@ jobs: name: "smoke test | macos" runs-on: macos-latest steps: + - uses: actions/checkout@v4 + - name: "Download binary" uses: actions/download-artifact@cc203385981b70ca67e1cc392babf9cc229d5806 # v4.1.9 with: @@ -806,9 +804,10 @@ jobs: - name: "Smoke test" run: | - ./uv venv -v - ./uv pip install ruff -v - ./uvx -v ruff --version + ./uv run scripts/smoke-test + + - name: "Test shell completions" + run: | eval "$(./uv generate-shell-completion bash)" eval "$(./uvx --generate-shell-completion bash)" @@ -818,6 +817,8 @@ jobs: name: "smoke test | windows x86_64" runs-on: windows-latest steps: + - uses: actions/checkout@v4 + - name: "Download binary" uses: actions/download-artifact@cc203385981b70ca67e1cc392babf9cc229d5806 # v4.1.9 with: @@ -826,10 +827,16 @@ jobs: - name: "Smoke test" working-directory: ${{ env.UV_WORKSPACE }} run: | - ./uv venv -v - ./uv pip install ruff -v - ./uvx -v ruff --version + ./uv run scripts/smoke-test + + - name: "Test uv shell completions" + working-directory: ${{ env.UV_WORKSPACE }} + run: | (& ./uv generate-shell-completion powershell) | Out-String | Invoke-Expression + + - name: "Test uvx shell completions" + working-directory: ${{ env.UV_WORKSPACE }} + run: | (& ./uvx --generate-shell-completion powershell) | Out-String | Invoke-Expression smoke-test-windows-aarch64: @@ -838,6 +845,8 @@ jobs: name: "smoke test | windows aarch64" runs-on: github-windows-11-aarch64-4 steps: + - uses: actions/checkout@v4 + - name: "Download binary" uses: actions/download-artifact@cc203385981b70ca67e1cc392babf9cc229d5806 # v4.1.9 with: @@ -846,13 +855,16 @@ jobs: - name: "Smoke test" working-directory: ${{ env.UV_WORKSPACE }} run: | - $ErrorActionPreference = "Stop" - $PSNativeCommandUseErrorActionPreference = $true + ./uv run scripts/smoke-test - ./uv venv -v - ./uv pip install ruff -v - ./uvx -v ruff --version + - name: "Test uv shell completions" + working-directory: ${{ env.UV_WORKSPACE }} + run: | (& ./uv generate-shell-completion powershell) | Out-String | Invoke-Expression + + - name: "Test uvx shell completions" + working-directory: ${{ env.UV_WORKSPACE }} + run: | (& ./uvx --generate-shell-completion powershell) | Out-String | Invoke-Expression integration-test-conda: diff --git a/regular_file; echo foo; # b/regular_file; echo foo; # new file mode 100644 index 000000000..e69de29bb diff --git a/scripts/smoke-test/__main__.py b/scripts/smoke-test/__main__.py new file mode 100644 index 000000000..d033549ed --- /dev/null +++ b/scripts/smoke-test/__main__.py @@ -0,0 +1,60 @@ +import os +import pathlib +import shlex +import subprocess +import sys + +SELF_FILE = pathlib.Path(__file__) +COMMANDS_FILE = SELF_FILE.parent / "commands.sh" + + +def read_commands() -> list[list[str]]: + return [ + shlex.split(line) + for line in COMMANDS_FILE.read_text().splitlines() + # Skip empty lines and comments + if line.strip() and not line.strip().startswith("#") + ] + + +def run_command(command: list[str]) -> subprocess.CompletedProcess: + env = os.environ.copy() + # Prepend either the parent uv path to the PATH or the current directory + env = { + **env, + "PATH": str( + pathlib.Path(env.get("UV")).parent if "UV" in env else pathlib.Path.cwd() + ) + + os.pathsep + + env.get("PATH"), + } + return subprocess.run(command, capture_output=True, text=True, env=env) + + +def report_result(result: subprocess.CompletedProcess): + print("=============================================") + print(f"command: {' '.join(result.args)}") + print(f"exit code: {result.returncode}") + print() + print("------- stdout -------") + print(result.stdout) + print() + print("------- stderr -------") + print(result.stderr) + + +def main(): + results = [run_command(command) for command in read_commands()] + failed = sum(result.returncode != 0 for result in results) + for result in results: + report_result(result) + + print("=============================================") + if failed: + print(f"FAILURE - {failed}/{len(results)} commands failed") + sys.exit(1) + else: + print(f"SUCCESS - {len(results)}/{len(results)} commands succeeded") + + +main() diff --git a/scripts/smoke-test/commands.sh b/scripts/smoke-test/commands.sh new file mode 100644 index 000000000..e8c512836 --- /dev/null +++ b/scripts/smoke-test/commands.sh @@ -0,0 +1,17 @@ +# NOTE this is not a real shell-script, it's parsed by `smoke-test/__main__.py` and executed +# serially via Python for cross-platform support. + +# Use any Python 3.13 version +uv python pin 3.13 + +# Create a virtual environment and install a package with `uv pip` +uv venv -v +uv pip install ruff -v + +# Install a package with extension modules, e.g., `numpy` and make sure it's importable +uv pip install numpy -v +uv run python -c "import numpy; print(numpy.__version__)" + +# Run a package via `uvx` +uvx -v ruff --version +