# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license name: "Setup uv" description: "Install uv and activate a venv on the newest preinstalled runner Python" inputs: python-version: description: "Python version for uv commands (default: newest preinstalled runner Python)" required: false default: "" activate-environment: description: "Create and activate a venv in the runner temp directory" required: false default: "true" enable-cache: description: "Cache uv downloads between workflow runs" required: false default: "false" ignore-empty-workdir: description: "Suppress the warning when the working directory is intentionally empty" required: false default: "false" runs: using: "composite" steps: - name: Use preinstalled Python if: inputs.activate-environment == 'true' || inputs.python-version != '' shell: bash env: PYTHON_VERSION: ${{ inputs.python-version }} run: | # Put the newest matching tool cache Python on PATH so uv uses it instead of downloading one dir=$(printf '%s\n' "$RUNNER_TOOL_CACHE/Python/${PYTHON_VERSION:-3}".*/*64 | sort -V | tail -1) if [ -d "$dir/bin" ]; then echo "$dir/bin" >> "$GITHUB_PATH"; elif [ -d "$dir" ]; then echo "$dir" >> "$GITHUB_PATH"; fi - name: Install latest uv id: latest continue-on-error: true uses: astral-sh/setup-uv@v10.2.0 with: version: latest python-version: ${{ inputs.python-version }} activate-environment: ${{ inputs.activate-environment }} venv-path: ${{ runner.temp }}/.venv enable-cache: ${{ inputs.enable-cache }} ignore-empty-workdir: ${{ inputs.ignore-empty-workdir }} ignore-nothing-to-cache: true - name: Install latest known uv if: steps.latest.outcome == 'failure' uses: astral-sh/setup-uv@v10.2.0 with: version: latest-known python-version: ${{ inputs.python-version }} activate-environment: ${{ inputs.activate-environment }} venv-path: ${{ runner.temp }}/.venv enable-cache: ${{ inputs.enable-cache }} ignore-empty-workdir: ${{ inputs.ignore-empty-workdir }} ignore-nothing-to-cache: true