diff --git a/.github/actions/restore-or-build-venv/action.yml b/.github/actions/restore-or-build-venv/action.yml new file mode 100644 index 00000000000..e9955c5a2cd --- /dev/null +++ b/.github/actions/restore-or-build-venv/action.yml @@ -0,0 +1,125 @@ +name: Set up Python and restore or build the venv +description: >- + Sets up uv and the managed interpreter, then restores the full venv from the + cache. On a miss it rebuilds the venv from requirements instead of + hard-failing, so jobs survive a transient miss when the entry is evicted under + the repo cache size limit. Only the prepare job sets save to true and writes + the cache, so the validating jobs add no extra cache pressure. + +inputs: + python-version: + description: The Python version uv should install and use. + required: true + uv-version: + description: The uv version setup-uv should install. + required: true + python-cache-key: + description: The shared python_cache_key from the info job. + required: true + uv-cache-dir: + description: The uv cache directory (env.UV_CACHE_DIR from the caller). + required: true + apt-cache-version: + description: The apt cache version (env.APT_CACHE_VERSION from the caller). + required: true + save: + description: Whether to save the rebuilt venv and uv cache. Only the prepare job should. + default: "false" + +outputs: + python-version: + description: The Python version uv reports as installed. + value: ${{ steps.python.outputs.python-version }} + +runs: + using: composite + steps: + - name: Set up uv and managed Python + id: python + uses: ./.github/actions/setup-uv-python + with: + uv-version: ${{ inputs.uv-version }} + python-version: ${{ inputs.python-version }} + - name: Restore full Python virtual environment + id: cache-venv + uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: venv + key: >- + ${{ runner.os }}-${{ runner.arch }}-${{ steps.python.outputs.python-version }}-${{ + inputs.python-cache-key }} + - name: Generate partial uv restore key + if: steps.cache-venv.outputs.cache-hit != 'true' + id: generate-uv-key + shell: bash + env: + RUNNER_OS: ${{ runner.os }} + RUNNER_ARCH: ${{ runner.arch }} + PYTHON_VERSION: ${{ steps.python.outputs.python-version }} + HASH_FILES: ${{ hashFiles('requirements.txt', 'requirements_all.txt', 'requirements_test.txt', 'homeassistant/package_constraints.txt') }} + run: | + partial_key="${RUNNER_OS}-${RUNNER_ARCH}-${PYTHON_VERSION}-uv-" + echo "partial_key=${partial_key}" >> $GITHUB_OUTPUT + echo "full_key=${partial_key}${HASH_FILES}" >> $GITHUB_OUTPUT + - name: Restore uv wheel cache + if: steps.cache-venv.outputs.cache-hit != 'true' + uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: ${{ inputs.uv-cache-dir }} + key: ${{ steps.generate-uv-key.outputs.full_key }} + restore-keys: ${{ steps.generate-uv-key.outputs.partial_key }} + # Only runs on a cache miss when the venv is rebuilt. Composite steps cannot + # set timeout-minutes, so a stuck apt download is bounded by the job-level + # timeout instead of a per-step cap. + - name: Install additional OS dependencies + if: steps.cache-venv.outputs.cache-hit != 'true' + uses: ./.github/actions/cache-apt-packages + with: + packages: >- + bluez + ffmpeg + libturbojpeg + libxml2-utils + libavcodec-dev + libavdevice-dev + libavfilter-dev + libavformat-dev + libavutil-dev + libswresample-dev + libswscale-dev + libudev-dev + version: ${{ inputs.apt-cache-version }} + execute_install_scripts: true + - name: Create Python virtual environment + if: steps.cache-venv.outputs.cache-hit != 'true' + id: create-venv + shell: bash + env: + PYTHON_VERSION: ${{ steps.python.outputs.python-version }} + run: | + uv venv venv --python "${PYTHON_VERSION}" + . venv/bin/activate + python --version + uv pip install -r requirements.txt + uv pip install -r requirements_all.txt -r requirements_test.txt + uv pip install -e . --config-settings editable_mode=compat + - name: Prune uv cache + if: inputs.save == 'true' && steps.cache-venv.outputs.cache-hit != 'true' + shell: bash + run: | + . venv/bin/activate + uv cache prune --ci + - name: Save uv wheel cache + if: inputs.save == 'true' && steps.cache-venv.outputs.cache-hit != 'true' + uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: ${{ inputs.uv-cache-dir }} + key: ${{ steps.generate-uv-key.outputs.full_key }} + - name: Save full Python virtual environment + if: always() && inputs.save == 'true' && steps.create-venv.outcome == 'success' + uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: venv + key: >- + ${{ runner.os }}-${{ runner.arch }}-${{ steps.python.outputs.python-version }}-${{ + inputs.python-cache-key }} diff --git a/.github/actions/setup-uv-python/action.yml b/.github/actions/setup-uv-python/action.yml new file mode 100644 index 00000000000..821640ac06b --- /dev/null +++ b/.github/actions/setup-uv-python/action.yml @@ -0,0 +1,46 @@ +name: Set up uv and managed Python +description: >- + Pins uv (avoids the raw.githubusercontent.com manifest fetch on cache miss) + and proactively installs the requested Python so cached venvs created with + `uv venv` resolve their interpreter symlinks in jobs that only restore the + venv. setup-uv alone only sets UV_PYTHON, it does not actually fetch the + interpreter until uv first uses it, so jobs that just activate the venv + blow up with broken symlinks on cache hit. + +inputs: + python-version: + description: The Python version uv should install and use. + required: true + uv-version: + description: The uv version setup-uv should install. + required: true + +outputs: + python-version: + description: The Python version uv reports as installed. + value: ${{ steps.uv.outputs.python-version }} + +runs: + using: composite + steps: + - name: Set up uv + id: uv + uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 + with: + version: ${{ inputs.uv-version }} + python-version: ${{ inputs.python-version }} + # Persist astral's managed Python across jobs so 'uv venv' below is + # fast on the second job onwards. + cache-python: true + # Lint-only and codegen jobs touch no Python deps, so the post-step + # cache save would otherwise abort the job. + ignore-nothing-to-cache: true + # setup-uv only sets UV_PYTHON; it does not fetch the interpreter until uv + # first uses it. Jobs that only restore and activate a cached venv never + # trigger that lazy install, so without this step they hit broken + # interpreter symlinks on a cache hit. + - name: Install Python interpreter + shell: bash + env: + PYTHON_VERSION: ${{ inputs.python-version }} + run: uv python install "${PYTHON_VERSION}" diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 265ea6a0c6f..e74f3e694ce 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -37,7 +37,7 @@ on: type: boolean env: - CACHE_VERSION: 3 + CACHE_VERSION: 4 MYPY_CACHE_VERSION: 1 HA_SHORT_VERSION: "2026.8" ADDITIONAL_PYTHON_VERSIONS: "[]" @@ -89,6 +89,8 @@ jobs: mariadb_groups: ${{ steps.info.outputs.mariadb_groups }} postgresql_groups: ${{ steps.info.outputs.postgresql_groups }} python_versions: ${{ steps.info.outputs.python_versions }} + default_python: ${{ steps.info.outputs.default_python }} + uv_version: ${{ steps.info.outputs.uv_version }} test_full_suite: ${{ steps.info.outputs.test_full_suite }} test_group_count: ${{ steps.info.outputs.test_group_count }} test_groups: ${{ steps.info.outputs.test_groups }} @@ -235,6 +237,11 @@ jobs: echo "postgresql_groups=${postgresql_groups}" >> $GITHUB_OUTPUT echo "python_versions: ${all_python_versions}" echo "python_versions=${all_python_versions}" >> $GITHUB_OUTPUT + echo "default_python: ${default_python}" + echo "default_python=${default_python}" >> $GITHUB_OUTPUT + uv_version=$(grep '^uv==' requirements.txt | cut -d'=' -f3) + echo "uv_version: ${uv_version}" + echo "uv_version=${uv_version}" >> $GITHUB_OUTPUT echo "test_full_suite: ${test_full_suite}" echo "test_full_suite=${test_full_suite}" >> $GITHUB_OUTPUT echo "integrations_glob: ${integrations_glob}" @@ -344,82 +351,18 @@ jobs: uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - - name: Set up Python ${{ matrix.python-version }} + - name: Set up Python ${{ matrix.python-version }} and build venv id: python - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 + uses: ./.github/actions/restore-or-build-venv with: + uv-version: ${{ needs.info.outputs.uv_version }} python-version: ${{ matrix.python-version }} - check-latest: true - - name: Restore base Python virtual environment - id: cache-venv - uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 - with: - path: venv - key: >- - ${{ runner.os }}-${{ runner.arch }}-${{ steps.python.outputs.python-version }}-${{ - needs.info.outputs.python_cache_key }} - - name: Generate partial uv restore key - if: steps.cache-venv.outputs.cache-hit != 'true' - id: generate-uv-key - env: - RUNNER_OS: ${{ runner.os }} - RUNNER_ARCH: ${{ runner.arch }} - PYTHON_VERSION: ${{ steps.python.outputs.python-version }} - HASH_FILES: ${{ hashFiles('requirements.txt', 'requirements_all.txt', 'requirements_test.txt', 'homeassistant/package_constraints.txt') }} - run: | - partial_key="${RUNNER_OS}-${RUNNER_ARCH}-${PYTHON_VERSION}-uv-" - echo "partial_key=${partial_key}" >> $GITHUB_OUTPUT - echo "full_key=${partial_key}${HASH_FILES}" >> $GITHUB_OUTPUT - - name: Restore uv wheel cache - if: steps.cache-venv.outputs.cache-hit != 'true' - uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 - with: - path: ${{ env.UV_CACHE_DIR }} - key: ${{ steps.generate-uv-key.outputs.full_key }} - restore-keys: ${{ steps.generate-uv-key.outputs.partial_key }} - - name: Install additional OS dependencies - if: steps.cache-venv.outputs.cache-hit != 'true' - timeout-minutes: 10 - uses: ./.github/actions/cache-apt-packages - with: - packages: >- - bluez - ffmpeg - libturbojpeg - libxml2-utils - libavcodec-dev - libavdevice-dev - libavfilter-dev - libavformat-dev - libavutil-dev - libswresample-dev - libswscale-dev - libudev-dev - version: ${{ env.APT_CACHE_VERSION }} - execute_install_scripts: true - - name: Read uv version from requirements.txt - if: steps.cache-venv.outputs.cache-hit != 'true' - id: read-uv-version - run: | - echo "version=$(grep '^uv==' requirements.txt | cut -d'=' -f3)" >> "$GITHUB_OUTPUT" - - name: Set up uv - if: steps.cache-venv.outputs.cache-hit != 'true' - uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 - with: - version: ${{ steps.read-uv-version.outputs.version }} - - name: Create Python virtual environment - if: steps.cache-venv.outputs.cache-hit != 'true' - id: create-venv - run: | - python -m venv venv - . venv/bin/activate - python --version - uv pip install -r requirements.txt - uv pip install -r requirements_all.txt -r requirements_test.txt - uv pip install -e . --config-settings editable_mode=compat + python-cache-key: ${{ needs.info.outputs.python_cache_key }} + uv-cache-dir: ${{ env.UV_CACHE_DIR }} + apt-cache-version: ${{ env.APT_CACHE_VERSION }} + save: "true" - name: Dump pip freeze run: | - python -m venv venv . venv/bin/activate python --version uv pip freeze >> pip_freeze.txt @@ -434,26 +377,6 @@ jobs: - name: Check dirty run: | ./script/check_dirty - - name: Prune uv cache - if: steps.cache-venv.outputs.cache-hit != 'true' - id: prune-uv-cache - run: | - . venv/bin/activate - uv cache prune --ci - - name: Save uv wheel cache - if: steps.cache-venv.outputs.cache-hit != 'true' - uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 - with: - path: ${{ env.UV_CACHE_DIR }} - key: ${{ steps.generate-uv-key.outputs.full_key }} - - name: Save base Python virtual environment - if: always() && steps.create-venv.outcome == 'success' - uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 - with: - path: venv - key: >- - ${{ runner.os }}-${{ runner.arch }}-${{ steps.python.outputs.python-version }}-${{ - needs.info.outputs.python_cache_key }} hassfest: name: Check hassfest @@ -478,21 +401,15 @@ jobs: with: packages: libturbojpeg version: ${{ env.APT_CACHE_VERSION }} - - name: Set up Python + - name: Set up Python and restore venv id: python - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 + uses: ./.github/actions/restore-or-build-venv with: - python-version-file: ".python-version" - check-latest: true - - name: Restore full Python virtual environment - id: cache-venv - uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 - with: - path: venv - fail-on-cache-miss: true - key: >- - ${{ runner.os }}-${{ runner.arch }}-${{ steps.python.outputs.python-version }}-${{ - needs.info.outputs.python_cache_key }} + uv-version: ${{ needs.info.outputs.uv_version }} + python-version: ${{ needs.info.outputs.default_python }} + python-cache-key: ${{ needs.info.outputs.python_cache_key }} + uv-cache-dir: ${{ env.UV_CACHE_DIR }} + apt-cache-version: ${{ env.APT_CACHE_VERSION }} - name: Run hassfest run: | . venv/bin/activate @@ -515,21 +432,15 @@ jobs: uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - - name: Set up Python + - name: Set up Python and restore venv id: python - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 + uses: ./.github/actions/restore-or-build-venv with: - python-version-file: ".python-version" - check-latest: true - - name: Restore full Python virtual environment - id: cache-venv - uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 - with: - path: venv - fail-on-cache-miss: true - key: >- - ${{ runner.os }}-${{ runner.arch }}-${{ steps.python.outputs.python-version }}-${{ - needs.info.outputs.python_cache_key }} + uv-version: ${{ needs.info.outputs.uv_version }} + python-version: ${{ needs.info.outputs.default_python }} + python-cache-key: ${{ needs.info.outputs.python_cache_key }} + uv-cache-dir: ${{ env.UV_CACHE_DIR }} + apt-cache-version: ${{ env.APT_CACHE_VERSION }} - name: Run gen_requirements_all.py run: | . venv/bin/activate @@ -553,13 +464,13 @@ jobs: persist-credentials: false - name: Set up Python id: python - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 + uses: ./.github/actions/setup-uv-python with: - python-version-file: ".python-version" - check-latest: true + uv-version: ${{ needs.info.outputs.uv_version }} + python-version: ${{ needs.info.outputs.default_python }} - name: Run gen_copilot_instructions.py run: | - python -m script.gen_copilot_instructions validate + uv run --no-project python -m script.gen_copilot_instructions validate dependency-review: name: Dependency review @@ -606,21 +517,15 @@ jobs: uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - - name: Set up Python ${{ matrix.python-version }} + - name: Set up Python ${{ matrix.python-version }} and restore venv id: python - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 + uses: ./.github/actions/restore-or-build-venv with: + uv-version: ${{ needs.info.outputs.uv_version }} python-version: ${{ matrix.python-version }} - check-latest: true - - name: Restore full Python ${{ matrix.python-version }} virtual environment - id: cache-venv - uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 - with: - path: venv - fail-on-cache-miss: true - key: >- - ${{ runner.os }}-${{ runner.arch }}-${{ steps.python.outputs.python-version }}-${{ - needs.info.outputs.python_cache_key }} + python-cache-key: ${{ needs.info.outputs.python_cache_key }} + uv-cache-dir: ${{ env.UV_CACHE_DIR }} + apt-cache-version: ${{ env.APT_CACHE_VERSION }} - name: Extract license data env: PYTHON_VERSION: ${{ matrix.python-version }} @@ -657,21 +562,15 @@ jobs: uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - - name: Set up Python + - name: Set up Python and restore venv id: python - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 + uses: ./.github/actions/restore-or-build-venv with: - python-version-file: ".python-version" - check-latest: true - - name: Restore full Python virtual environment - id: cache-venv - uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 - with: - path: venv - fail-on-cache-miss: true - key: >- - ${{ runner.os }}-${{ runner.arch }}-${{ steps.python.outputs.python-version }}-${{ - needs.info.outputs.python_cache_key }} + uv-version: ${{ needs.info.outputs.uv_version }} + python-version: ${{ needs.info.outputs.default_python }} + python-cache-key: ${{ needs.info.outputs.python_cache_key }} + uv-cache-dir: ${{ env.UV_CACHE_DIR }} + apt-cache-version: ${{ env.APT_CACHE_VERSION }} - name: Register pylint problem matcher run: | echo "::add-matcher::.github/workflows/matchers/pylint.json" @@ -710,21 +609,15 @@ jobs: uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - - name: Set up Python + - name: Set up Python and restore venv id: python - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 + uses: ./.github/actions/restore-or-build-venv with: - python-version-file: ".python-version" - check-latest: true - - name: Restore full Python virtual environment - id: cache-venv - uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 - with: - path: venv - fail-on-cache-miss: true - key: >- - ${{ runner.os }}-${{ runner.arch }}-${{ steps.python.outputs.python-version }}-${{ - needs.info.outputs.python_cache_key }} + uv-version: ${{ needs.info.outputs.uv_version }} + python-version: ${{ needs.info.outputs.default_python }} + python-cache-key: ${{ needs.info.outputs.python_cache_key }} + uv-cache-dir: ${{ env.UV_CACHE_DIR }} + apt-cache-version: ${{ env.APT_CACHE_VERSION }} - name: Register pylint problem matcher run: | echo "::add-matcher::.github/workflows/matchers/pylint.json" @@ -761,27 +654,21 @@ jobs: uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - - name: Set up Python - id: python - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 - with: - python-version-file: ".python-version" - check-latest: true - name: Generate partial mypy restore key id: generate-mypy-key run: | mypy_version=$(cat requirements_test.txt | grep 'mypy.*=' | cut -d '=' -f 3) echo "version=${mypy_version}" >> $GITHUB_OUTPUT echo "key=mypy-${MYPY_CACHE_VERSION}-${mypy_version}-${HA_SHORT_VERSION}-$(date -u '+%Y-%m-%dT%H:%M:%s')" >> $GITHUB_OUTPUT - - name: Restore full Python virtual environment - id: cache-venv - uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + - name: Set up Python and restore venv + id: python + uses: ./.github/actions/restore-or-build-venv with: - path: venv - fail-on-cache-miss: true - key: >- - ${{ runner.os }}-${{ runner.arch }}-${{ steps.python.outputs.python-version }}-${{ - needs.info.outputs.python_cache_key }} + uv-version: ${{ needs.info.outputs.uv_version }} + python-version: ${{ needs.info.outputs.default_python }} + python-cache-key: ${{ needs.info.outputs.python_cache_key }} + uv-cache-dir: ${{ env.UV_CACHE_DIR }} + apt-cache-version: ${{ env.APT_CACHE_VERSION }} - name: Restore mypy cache uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: @@ -838,21 +725,15 @@ jobs: libturbojpeg version: ${{ env.APT_CACHE_VERSION }} execute_install_scripts: true - - name: Set up Python + - name: Set up Python and restore venv id: python - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 + uses: ./.github/actions/restore-or-build-venv with: - python-version-file: ".python-version" - check-latest: true - - name: Restore full Python virtual environment - id: cache-venv - uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 - with: - path: venv - fail-on-cache-miss: true - key: >- - ${{ runner.os }}-${{ runner.arch }}-${{ steps.python.outputs.python-version }}-${{ - needs.info.outputs.python_cache_key }} + uv-version: ${{ needs.info.outputs.uv_version }} + python-version: ${{ needs.info.outputs.default_python }} + python-cache-key: ${{ needs.info.outputs.python_cache_key }} + uv-cache-dir: ${{ env.UV_CACHE_DIR }} + apt-cache-version: ${{ env.APT_CACHE_VERSION }} - name: Run split_tests.py env: TEST_GROUP_COUNT: ${{ needs.info.outputs.test_group_count }} @@ -903,21 +784,15 @@ jobs: libxml2-utils version: ${{ env.APT_CACHE_VERSION }} execute_install_scripts: true - - name: Set up Python ${{ matrix.python-version }} + - name: Set up Python ${{ matrix.python-version }} and restore venv id: python - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 + uses: ./.github/actions/restore-or-build-venv with: + uv-version: ${{ needs.info.outputs.uv_version }} python-version: ${{ matrix.python-version }} - check-latest: true - - name: Restore full Python ${{ matrix.python-version }} virtual environment - id: cache-venv - uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 - with: - path: venv - fail-on-cache-miss: true - key: >- - ${{ runner.os }}-${{ runner.arch }}-${{ steps.python.outputs.python-version }}-${{ - needs.info.outputs.python_cache_key }} + python-cache-key: ${{ needs.info.outputs.python_cache_key }} + uv-cache-dir: ${{ env.UV_CACHE_DIR }} + apt-cache-version: ${{ env.APT_CACHE_VERSION }} - name: Register Python problem matcher run: | echo "::add-matcher::.github/workflows/matchers/python.json" @@ -1045,21 +920,15 @@ jobs: libxml2-utils version: ${{ env.APT_CACHE_VERSION }} execute_install_scripts: true - - name: Set up Python ${{ matrix.python-version }} + - name: Set up Python ${{ matrix.python-version }} and restore venv id: python - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 + uses: ./.github/actions/restore-or-build-venv with: + uv-version: ${{ needs.info.outputs.uv_version }} python-version: ${{ matrix.python-version }} - check-latest: true - - name: Restore full Python ${{ matrix.python-version }} virtual environment - id: cache-venv - uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 - with: - path: venv - fail-on-cache-miss: true - key: >- - ${{ runner.os }}-${{ runner.arch }}-${{ steps.python.outputs.python-version }}-${{ - needs.info.outputs.python_cache_key }} + python-cache-key: ${{ needs.info.outputs.python_cache_key }} + uv-cache-dir: ${{ env.UV_CACHE_DIR }} + apt-cache-version: ${{ env.APT_CACHE_VERSION }} - name: Register Python problem matcher run: | echo "::add-matcher::.github/workflows/matchers/python.json" @@ -1201,21 +1070,15 @@ jobs: with: packages: postgresql-server-dev-14 version: ${{ env.APT_CACHE_VERSION }} - - name: Set up Python ${{ matrix.python-version }} + - name: Set up Python ${{ matrix.python-version }} and restore venv id: python - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 + uses: ./.github/actions/restore-or-build-venv with: + uv-version: ${{ needs.info.outputs.uv_version }} python-version: ${{ matrix.python-version }} - check-latest: true - - name: Restore full Python ${{ matrix.python-version }} virtual environment - id: cache-venv - uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 - with: - path: venv - fail-on-cache-miss: true - key: >- - ${{ runner.os }}-${{ runner.arch }}-${{ steps.python.outputs.python-version }}-${{ - needs.info.outputs.python_cache_key }} + python-cache-key: ${{ needs.info.outputs.python_cache_key }} + uv-cache-dir: ${{ env.UV_CACHE_DIR }} + apt-cache-version: ${{ env.APT_CACHE_VERSION }} - name: Register Python problem matcher run: | echo "::add-matcher::.github/workflows/matchers/python.json" @@ -1369,21 +1232,15 @@ jobs: libxml2-utils version: ${{ env.APT_CACHE_VERSION }} execute_install_scripts: true - - name: Set up Python ${{ matrix.python-version }} + - name: Set up Python ${{ matrix.python-version }} and restore venv id: python - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 + uses: ./.github/actions/restore-or-build-venv with: + uv-version: ${{ needs.info.outputs.uv_version }} python-version: ${{ matrix.python-version }} - check-latest: true - - name: Restore full Python ${{ matrix.python-version }} virtual environment - id: cache-venv - uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 - with: - path: venv - fail-on-cache-miss: true - key: >- - ${{ runner.os }}-${{ runner.arch }}-${{ steps.python.outputs.python-version }}-${{ - needs.info.outputs.python_cache_key }} + python-cache-key: ${{ needs.info.outputs.python_cache_key }} + uv-cache-dir: ${{ env.UV_CACHE_DIR }} + apt-cache-version: ${{ env.APT_CACHE_VERSION }} - name: Register Python problem matcher run: | echo "::add-matcher::.github/workflows/matchers/python.json"