測驗:uv 進階技巧 – 工具管理與 CI/CD 整合
共 5 題,點選答案後會立即顯示結果
1. uvx 指令的主要用途是什麼?
2. 你想用 pytest 測試專案中的程式碼,應該使用哪個指令?
3. uv tool install ruff 和 uvx ruff 的主要差別是什麼?
4. 在 CI/CD 中,uv cache prune --ci 會保留什麼類型的快取?
5. 在 GitHub Actions 中使用 setup-uv 時,如何啟用快取功能?
前言
經過前三篇的學習,你已經掌握了 uv 的專案管理能力。這篇是系列的最後一篇,我們要來看 uv 更強大的兩個面向:工具管理和 CI/CD 整合。
當你使用 AI 輔助開發時,經常會需要執行各種 Python 工具,例如:
- 「幫我用 black 格式化這個檔案」
- 「用 ruff 檢查程式碼」
- 「執行 pytest 跑測試」
這時候,知道如何快速執行這些工具就變得很重要。
學習目標
讀完本篇後,你能夠:
- 使用
uvx執行一次性 Python 工具 - 使用
uv tool管理全域工具 - 設定 uv 快取策略優化效能
- 在 GitHub Actions 中整合 uv
一、工具執行:uvx 命令
1.1 uvx 是什麼?
uvx 是 uv tool run 的簡寫,讓你可以不需要安裝就直接執行 Python 工具。
# 傳統方式:先安裝再執行
pip install black
black myfile.py
# uv 方式:直接執行,不需預先安裝
uvx black myfile.py
Code language: CSS (css)背後原理:uvx 會在背景建立一個暫時的隔離環境,安裝工具後執行。執行完後環境會被快取(不是刪除),下次執行同樣的工具會更快。
1.2 常用 uvx 範例
# 格式化程式碼
uvx black src/
uvx isort .
# 程式碼檢查
uvx ruff check .
uvx mypy src/
# 執行其他工具
uvx cowsay "Hello from uv!"
uvx httpie https://api.github.com
Code language: PHP (php)1.3 指定版本
有時候你需要特定版本的工具:
# 使用 @ 指定版本
uvx black@24.4.2 src/
uvx ruff@0.3.0 check .
# 使用 --from 指定版本範圍
uvx --from 'black>=24.0.0,<25.0.0' black src/
uvx --from 'ruff>0.2.0,<0.3.0' ruff check
Code language: PHP (php)1.4 套件名與指令名不同的情況
有些套件的名稱和它提供的指令不同:
# httpie 套件提供的指令是 http
uvx --from httpie http https://api.github.com
# mkdocs-material 套件,指令是 mkdocs
uvx --from mkdocs-material mkdocs serve
Code language: PHP (php)1.5 帶入額外依賴
某些工具需要額外的套件才能正常運作:
# mkdocs 配合 material 主題
uvx --with mkdocs-material mkdocs build
# mypy 配合額外功能(使用 extras 語法)
uvx --from 'mypy[faster-cache,reports]' mypy src/
Code language: PHP (php)1.6 指定 Python 版本
# 用特定 Python 版本執行工具
uvx --python 3.10 black src/
uvx --python 3.12 ruff check .
Code language: PHP (php)二、uvx vs uv run:何時用哪個?
這是很多人會搞混的地方,讓我們釐清:
| 指令 | 用途 | 環境 |
|---|---|---|
uvx |
執行獨立工具 | 隔離的暫時環境 |
uv run |
執行專案相關指令 | 專案的虛擬環境 |
判斷原則
用 uvx 當工具不需要存取你的專案程式碼:
uvx black src/ # 格式化工具,只讀取檔案
uvx cowsay "Hello" # 獨立工具
uvx httpie GET url # HTTP 工具
Code language: PHP (php)用 uv run 當工具需要你的專案依賴:
uv run pytest tests/ # pytest 需要 import 你的專案
uv run mypy src/ # mypy 需要檢查你的專案型別
uv run python main.py # 執行專案程式碼
Code language: PHP (php)實際範例
假設你的專案有個 math_utils.py,你想用 pytest 測試它:
# 錯誤:uvx 的環境找不到你的專案模組
uvx pytest tests/
# ImportError: No module named 'math_utils'
# 正確:uv run 在專案環境中執行
uv run pytest tests/
# 測試正常執行
Code language: PHP (php)三、工具管理:uv tool 指令
如果某個工具你經常使用,每次用 uvx 都要等它建立環境太慢了。這時可以用 uv tool install 把工具「安裝」到全域。
3.1 安裝全域工具
# 安裝工具
uv tool install ruff
uv tool install black
uv tool install httpie
# 安裝特定版本
uv tool install 'black>=24.0.0,<25.0.0'
Code language: PHP (php)安裝後,這些指令會加入你的 PATH,可以直接使用:
# 不需要 uvx 前綴,直接執行
ruff check .
black src/
http GET https://api.github.com
Code language: PHP (php)3.2 列出已安裝的工具
uv tool list
Code language: PHP (php)輸出範例:
black v24.4.2
- black
- blackd
ruff v0.4.4
- ruff
httpie v3.2.2
- http
- https
- httpie
Code language: CSS (css)3.3 升級工具
# 升級單一工具
uv tool upgrade ruff
# 升級所有工具
uv tool upgrade --all
Code language: PHP (php)升級會遵守安裝時的版本限制。例如安裝時用 black>=24.0.0,<25.0.0,升級只會在這個範圍內找新版本。
3.4 移除工具
uv tool uninstall ruff
uv tool uninstall black
3.5 查看工具目錄
# 顯示工具安裝的目錄位置
uv tool dir
Code language: PHP (php)四、快取策略
uv 的快取機制是它快速的關鍵之一。了解如何管理快取,可以幫你節省空間或解決問題。
4.1 快取目錄位置
uv 的快取位置(優先順序由高到低):
--cache-dir參數UVCACHEDIR環境變數pyproject.toml中的tool.uv.cache-dir- 系統預設位置:
- Linux/macOS:
~/.cache/uv - Windows:
%LOCALAPPDATA%\uv\cache
- Linux/macOS:
4.2 自訂快取目錄
# 使用環境變數
export UV_CACHE_DIR=/path/to/custom/cache
# 或在指令中指定
uv sync --cache-dir /path/to/cache
Code language: PHP (php)4.3 停用快取
有時候你需要強制重新下載套件(例如懷疑快取有問題):
# 完全不使用快取(使用暫時目錄)
uv sync --no-cache
# 強制刷新快取(更新但保留快取)
uv sync --refresh
Code language: PHP (php)建議:優先使用 --refresh,它會更新快取內容供未來使用。--no-cache 只在排查問題時使用。
4.4 清理快取
# 查看快取大小
du -sh ~/.cache/uv
# 清理所有快取
uv cache clean
# 只清理特定套件的快取
uv cache clean ruff
uv cache clean black numpy
# 清理未使用的快取(推薦)
uv cache prune
Code language: PHP (php)4.5 CI 專用清理
在 CI/CD 中,推薦使用這個指令來優化快取:
uv cache prune --ci
這會移除預建的 wheels 和解壓的原始碼,但保留從原始碼編譯的 wheels。
原因:預建的 wheels 重新下載很快,但從原始碼編譯的 wheels 很慢,所以保留後者更划算。
五、GitHub Actions 整合
uv 在 CI/CD 中特別好用,因為它的速度優勢在這裡更明顯。
5.1 基本設定
使用官方的 astral-sh/setup-uv action:
name: CI
on:
push:
branches: [main]
pull_request:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Install dependencies
run: uv sync --locked
- name: Run tests
run: uv run pytest tests/
Code language: HTTP (http)5.2 指定 uv 版本
建議鎖定版本以確保一致性:
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
version: "0.9.26"
Code language: JavaScript (javascript)5.3 多版本測試(矩陣策略)
測試多個 Python 版本是 CI 的常見需求:
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13"]
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: uv sync --locked --all-extras --dev
- name: Run tests
run: uv run pytest tests/
Code language: JavaScript (javascript)5.4 啟用快取
setup-uv 內建快取支援:
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
enable-cache: true
Code language: JavaScript (javascript)或手動設定更細緻的快取策略:
env:
UV_CACHE_DIR: /tmp/.uv-cache
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Restore cache
uses: actions/cache@v4
with:
path: /tmp/.uv-cache
key: uv-${{ runner.os }}-${{ hashFiles('uv.lock') }}
restore-keys: |
uv-${{ runner.os }}-
- name: Install dependencies
run: uv sync --locked
- name: Run tests
run: uv run pytest tests/
- name: Minimize cache
run: uv cache prune --ci
Code language: JavaScript (javascript)5.5 完整 CI 範例
這是一個包含程式碼檢查、測試、多版本的完整範例:
name: CI
on:
push:
branches: [main]
pull_request:
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
enable-cache: true
- name: Run linting
run: |
uvx ruff check .
uvx ruff format --check .
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.10", "3.11", "3.12"]
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
python-version: ${{ matrix.python-version }}
enable-cache: true
- name: Install dependencies
run: uv sync --locked --dev
- name: Run tests
run: uv run pytest tests/ -v
- name: Minimize cache
run: uv cache prune --ci
Code language: JavaScript (javascript)注意 lint job 使用 uvx 是因為 ruff 不需要專案依賴;test job 使用 uv run pytest 是因為 pytest 需要存取專案程式碼。
六、實用技巧整理
6.1 Python 版本管理
uv 也可以管理 Python 版本:
# 安裝 Python
uv python install 3.12
# 列出可用版本
uv python list
# 在專案中指定版本
uv python pin 3.12
Code language: PHP (php)6.2 離線安裝
在沒有網路的環境中,可以預先準備快取:
# 有網路時:下載並快取
uv sync
# 離線時:使用快取安裝
uv sync --offline
Code language: PHP (php)6.3 效能調校
# 平行下載(預設已啟用)
uv sync --concurrent-downloads 10
# 跳過更新檢查(當你確定 lock 檔是最新的)
uv sync --frozen
Code language: PHP (php)6.4 環境變數速查
| 變數 | 說明 |
|---|---|
UV_CACHE_DIR |
自訂快取目錄 |
UV_NO_CACHE |
停用快取 |
UV_PYTHON |
指定 Python 版本 |
UV_SYSTEM_PYTHON |
允許使用系統 Python |
UV_PROJECT_ENVIRONMENT |
指定虛擬環境位置 |
七、常見問題
Q1:uvx 執行很慢?
第一次執行某個工具時,uvx 需要下載並建立環境,會比較慢。之後因為有快取,就會很快。如果經常使用某個工具,考慮用 uv tool install 安裝到全域。
Q2:快取佔用太多空間?
# 查看快取大小
du -sh ~/.cache/uv
# 清理未使用的快取
uv cache prune
# 完全清空快取
uv cache clean
Code language: PHP (php)Q3:CI 中每次都重新安裝?
確認你有啟用快取:
- uses: astral-sh/setup-uv@v7
with:
enable-cache: true
Code language: JavaScript (javascript)也確保 cache key 包含 uv.lock 的 hash,這樣依賴沒變時就能命中快取。
Q4:tool install 的工具找不到?
確認 ~/.local/bin 在你的 PATH 中:
echo $PATH | tr ':' '\n' | grep local
# 如果沒有,加入 shell 設定檔
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
Code language: PHP (php)總結
這篇文章涵蓋了 uv 的進階使用技巧:
- uvx:快速執行一次性工具,不需預先安裝
- uv tool:管理全域工具,適合常用指令
- 快取策略:透過
UVCACHEDIR和uv cache指令管理快取 - CI/CD 整合:使用
astral-sh/setup-uvaction,搭配矩陣測試和快取
恭喜你完成了整個系列!你現在已經掌握了 uv 從基礎到進階的完整知識。
系列回顧
- 第 1 篇:uv 安裝與專案建立
- 第 2 篇:依賴管理與 lock 檔
- 第 3 篇:虛擬環境與專案設定
- 第 4 篇:工具管理與 CI/CD 整合(本篇)
延伸資源
進階測驗:uv 進階技巧 – 工具管理與 CI/CD 整合
共 5 題,包含情境題與錯誤診斷題。