| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -17,37 +17,29 @@ jobs: | |||
| 17 | 17 | - name: Checkout | |
| 18 | 18 | uses: actions/checkout@v4 | |
| 19 | 19 | ||
| 20 | - - name: Set up Python ${{ matrix.python-version }} | ||
| 21 | - uses: actions/setup-python@v5 | ||
| 20 | + - name: Set up uv (Python ${{ matrix.python-version }}) | ||
| 21 | + uses: astral-sh/setup-uv@v10.0.1 | ||
| 22 | 22 | with: | |
| 23 | + enable-cache: true | ||
| 23 | 24 | python-version: ${{ matrix.python-version }} | |
| 24 | 25 | ||
| 25 | - - name: Install tools | ||
| 26 | - run: | | ||
| 27 | - python -m pip install --upgrade pip | ||
| 28 | - pip install -e ".[ci]" | ||
| 26 | + - name: Install dependencies | ||
| 27 | + run: uv sync --locked --group dev | ||
| 29 | 28 | ||
| 30 | 29 | - name: Lint (Ruff) | |
| 31 | - run: | | ||
| 32 | - ruff check . | ||
| 30 | + run: uv run ruff check . | ||
| 33 | 31 | ||
| 34 | 32 | - name: Format check (Black) | |
| 35 | - run: | | ||
| 36 | - black --check src examples tests | ||
| 33 | + run: uv run black --check src examples tests | ||
| 37 | 34 | ||
| 38 | 35 | - name: Type check (MyPy) | |
| 39 | - run: | | ||
| 40 | - mypy --install-types --non-interactive | ||
| 41 | - | ||
| 42 | - - name: Install package | ||
| 43 | - run: | | ||
| 44 | - pip install . | ||
| 36 | + run: uv run mypy | ||
| 45 | 37 | ||
| 38 | + # Produces the sdist and wheel through the setuptools backend. Note | ||
| 39 | + # this builds but does not install them, so the previous non-editable | ||
| 40 | + # install smoke test is not replaced. | ||
| 46 | 41 | - name: Build package | |
| 47 | - run: | | ||
| 48 | - pip install build | ||
| 49 | - python -m build | ||
| 42 | + run: uv build | ||
| 50 | 43 | ||
| 51 | 44 | - name: Run tests | |
| 52 | - run: | | ||
| 53 | - pytest -q | ||
| 45 | + run: uv run pytest -q | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -14,16 +14,16 @@ jobs: | |||
| 14 | 14 | runs-on: ubuntu-latest | |
| 15 | 15 | steps: | |
| 16 | 16 | - uses: actions/checkout@v4 | |
| 17 | - - uses: actions/setup-python@v5 | ||
| 17 | + - uses: astral-sh/setup-uv@v10.0.1 | ||
| 18 | 18 | with: | |
| 19 | + enable-cache: true | ||
| 19 | 20 | python-version: '3.11' | |
| 21 | + # `uv sync` installs the project itself, which mkdocstrings needs in | ||
| 22 | + # order to import and introspect it. | ||
| 20 | 23 | - name: Install docs deps | |
| 21 | - run: | | ||
| 22 | - python -m pip install --upgrade pip | ||
| 23 | - pip install -e ".[docs]" | ||
| 24 | + run: uv sync --locked --group docs | ||
| 24 | 25 | - name: Build site | |
| 25 | - run: | | ||
| 26 | - python -m mkdocs build --strict | ||
| 26 | + run: uv run mkdocs build --strict | ||
| 27 | 27 | - name: Deploy to GitHub Pages | |
| 28 | 28 | if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| 29 | 29 | uses: peaceiris/actions-gh-pages@v3 | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -60,9 +60,10 @@ jobs: | |||
| 60 | 60 | - name: Checkout | |
| 61 | 61 | uses: actions/checkout@v4 | |
| 62 | 62 | ||
| 63 | - - name: Set up Python | ||
| 64 | - uses: actions/setup-python@v5 | ||
| 63 | + - name: Set up uv | ||
| 64 | + uses: astral-sh/setup-uv@v10.0.1 | ||
| 65 | 65 | with: | |
| 66 | + enable-cache: true | ||
| 66 | 67 | python-version: '3.11' | |
| 67 | 68 | ||
| 68 | 69 | - name: Set up Java 17 | |
@@ -72,7 +73,7 @@ jobs: | |||
| 72 | 73 | java-version: '17' | |
| 73 | 74 | ||
| 74 | 75 | - name: Install PythonNative | |
| 75 | - run: pip install -e . | ||
| 76 | + run: uv sync --locked | ||
| 76 | 77 | ||
| 77 | 78 | - name: Install Maestro | |
| 78 | 79 | run: | | |
@@ -85,12 +86,18 @@ jobs: | |||
| 85 | 86 | sudo udevadm control --reload-rules | |
| 86 | 87 | sudo udevadm trigger --name-match=kvm | |
| 87 | 88 | ||
| 89 | + # The emulator step runs its script through a login shell, which | ||
| 90 | + # sources /etc/profile and can rewrite PATH. Confirm uv survives that | ||
| 91 | + # here, in seconds, rather than after a multi-minute emulator boot. | ||
| 92 | + - name: Verify uv is reachable in a login shell | ||
| 93 | + run: bash -lc 'command -v uv && uv --version' | ||
| 94 | + | ||
| 88 | 95 | - name: Build, install, and run E2E tests | |
| 89 | 96 | uses: reactivecircus/android-emulator-runner@v2 | |
| 90 | 97 | with: | |
| 91 | 98 | api-level: 31 | |
| 92 | 99 | arch: x86_64 | |
| 93 | - script: bash -lc "./scripts/run-e2e.sh android ${{ matrix.suites }}" | ||
| 100 | + script: bash -lc "uv run ./scripts/run-e2e.sh android ${{ matrix.suites }}" | ||
| 94 | 101 | ||
| 95 | 102 | # Maestro writes per-flow debug output (command log, view-hierarchy | |
| 96 | 103 | # dumps, failure screenshots) under ~/.maestro/tests. Surface it when | |
@@ -149,13 +156,14 @@ jobs: | |||
| 149 | 156 | - name: Checkout | |
| 150 | 157 | uses: actions/checkout@v4 | |
| 151 | 158 | ||
| 152 | - - name: Set up Python | ||
| 153 | - uses: actions/setup-python@v5 | ||
| 159 | + - name: Set up uv | ||
| 160 | + uses: astral-sh/setup-uv@v10.0.1 | ||
| 154 | 161 | with: | |
| 162 | + enable-cache: true | ||
| 155 | 163 | python-version: '3.11' | |
| 156 | 164 | ||
| 157 | 165 | - name: Install PythonNative | |
| 158 | - run: pip install -e . | ||
| 166 | + run: uv sync --locked | ||
| 159 | 167 | ||
| 160 | 168 | # Maestro drives iOS simulators with its own bundled XCTest | |
| 161 | 169 | # runner; idb-companion (once installed here) hasn't been needed | |
@@ -167,7 +175,7 @@ jobs: | |||
| 167 | 175 | echo "$HOME/.maestro/bin" >> $GITHUB_PATH | |
| 168 | 176 | ||
| 169 | 177 | - name: Build and run E2E tests | |
| 170 | - run: ./scripts/run-e2e.sh ios ${{ matrix.suites }} | ||
| 178 | + run: uv run ./scripts/run-e2e.sh ios ${{ matrix.suites }} | ||
| 171 | 179 | env: | |
| 172 | 180 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| 173 | 181 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -22,14 +22,12 @@ jobs: | |||
| 22 | 22 | with: | |
| 23 | 23 | fetch-depth: 0 | |
| 24 | 24 | ||
| 25 | - - name: Set up Python | ||
| 26 | - uses: actions/setup-python@v5 | ||
| 25 | + - name: Set up uv | ||
| 26 | + uses: astral-sh/setup-uv@v10.0.1 | ||
| 27 | 27 | with: | |
| 28 | + enable-cache: true | ||
| 28 | 29 | python-version: '3.12' | |
| 29 | 30 | ||
| 30 | - - name: Install build tools | ||
| 31 | - run: python -m pip install -U pip build | ||
| 32 | - | ||
| 33 | 31 | # TEMPORARY: inlined replacement for the | |
| 34 | 32 | # python-semantic-release/python-semantic-release@v9 action. That | |
| 35 | 33 | # action builds its Docker image at job time with GitPython | |
@@ -46,7 +44,7 @@ jobs: | |||
| 46 | 44 | run: | | |
| 47 | 45 | git config user.name "github-actions" | |
| 48 | 46 | git config user.email "actions@github.com" | |
| 49 | - pip install "python-semantic-release==9.21.2" "gitpython<3.1.60" | ||
| 47 | + uv tool install "python-semantic-release==9.21.2" --with "gitpython<3.1.60" | ||
| 50 | 48 | tags_before=$(git tag | wc -l) | |
| 51 | 49 | semantic-release -v version | |
| 52 | 50 | tags_after=$(git tag | wc -l) | |
@@ -56,10 +54,9 @@ jobs: | |||
| 56 | 54 | echo "released=false" >> "$GITHUB_OUTPUT" | |
| 57 | 55 | fi | |
| 58 | 56 | ||
| 59 | - - name: Build package | ||
| 60 | - if: steps.release.outputs.released == 'true' | ||
| 61 | - run: python -m build | ||
| 62 | - | ||
| 57 | + # The distributions come from `build_command` in | ||
| 58 | + # [tool.semantic_release], which runs `uv build` after PSR stamps the | ||
| 59 | + # new version, so there is no separate build step here. | ||
| 63 | 60 | - name: Publish to PyPI | |
| 64 | 61 | if: steps.release.outputs.released == 'true' | |
| 65 | 62 | uses: pypa/gh-action-pypi-publish@release/v1 | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -4,31 +4,49 @@ Thanks for your interest in contributing. This repository contains the PythonNat | |||
| 4 | 4 | ||
| 5 | 5 | ## Quick start | |
| 6 | 6 | ||
| 7 | - Development uses Python ≥ 3.10. | ||
| 7 | + Development uses Python ≥ 3.10 and [uv](https://docs.astral.sh/uv/) as the | ||
| 8 | + only prerequisite. `uv sync` creates and updates `.venv` itself, so there's no | ||
| 9 | + virtual environment to make and nothing to activate. | ||
| 8 | 10 | ||
| 9 | 11 | ```bash | |
| 10 | - # one-shot: creates .venv, syncs CI deps, runs every CI check | ||
| 11 | - # (requires uv: https://docs.astral.sh/uv/getting-started/installation/) | ||
| 12 | + # install the project and its dev tooling into .venv, exactly as CI does | ||
| 13 | + uv sync --locked --group dev | ||
| 14 | + | ||
| 15 | + # one-shot: runs every CI check, in the same order | ||
| 12 | 16 | ./scripts/check.sh | |
| 13 | 17 | ||
| 14 | - # Run individual steps if you only want one | ||
| 15 | - pytest -q | ||
| 16 | - ruff check . | ||
| 17 | - black src examples tests | ||
| 18 | + # run individual steps if you only want one | ||
| 19 | + uv run pytest -q | ||
| 20 | + uv run ruff check . | ||
| 21 | + uv run black src examples tests | ||
| 18 | 22 | ``` | |
| 19 | 23 | ||
| 20 | - Common library and CLI entry points: | ||
| 24 | + Dependencies are pinned in `uv.lock`, which is committed, so local runs and CI | ||
| 25 | + resolve identically. `--locked` fails rather than silently re-resolving if the | ||
| 26 | + lockfile has drifted from `pyproject.toml`. Upgrading a dependency is a | ||
| 27 | + deliberate `uv lock --upgrade-package <name>` in its own commit. | ||
| 28 | + | ||
| 29 | + Common library and CLI entry points. `uv run` puts `.venv/bin` on the path | ||
| 30 | + for one command, so `pn` resolves without activating anything. Each block | ||
| 31 | + starts from the repository root. | ||
| 21 | 32 | ||
| 22 | 33 | ```bash | |
| 23 | 34 | # CLI help | |
| 24 | - pn --help | ||
| 35 | + uv run pn --help | ||
| 25 | 36 | ||
| 26 | - # create a new sample app from the bundled templates | ||
| 27 | - pn init my_app | ||
| 37 | + # scaffold a sample app into ./my_app/, then work inside it | ||
| 38 | + uv run pn init my_app | ||
| 28 | 39 | cd my_app | |
| 40 | + uv run pn run android | ||
| 41 | + ``` | ||
| 29 | 42 | ||
| 43 | + `uv run` looks upward for the nearest project, so it keeps using the | ||
| 44 | + repository's `.venv` from a subdirectory. The bundled example works the same | ||
| 45 | + way: | ||
| 46 | + | ||
| 47 | + ```bash | ||
| 30 | 48 | # run the Hello World example | |
| 31 | - cd examples/hello-world && pn run android | ||
| 49 | + cd examples/hello-world && uv run pn run android | ||
| 32 | 50 | ``` | |
| 33 | 51 | ||
| 34 | 52 | ## Claiming an issue | |
@@ -70,10 +88,12 @@ Unsolicited pull requests for issues that are already assigned or already have a | |||
| 70 | 88 | Common commands: | |
| 71 | 89 | ||
| 72 | 90 | ```bash | |
| 73 | - ./scripts/check.sh # run all CI checks (mirrors ci.yml) | ||
| 74 | - pytest -q # run tests | ||
| 75 | - ruff check . # lint | ||
| 76 | - black src examples tests # format | ||
| 91 | + ./scripts/check.sh # run all CI checks (mirrors ci.yml) | ||
| 92 | + uv sync --locked --group dev # install/refresh .venv from the lockfile | ||
| 93 | + uv run pytest -q # run tests | ||
| 94 | + uv run ruff check . # lint | ||
| 95 | + uv run black src examples tests # format | ||
| 96 | + uv run --group docs mkdocs serve # preview the docs site locally | ||
| 77 | 97 | ``` | |
| 78 | 98 | ||
| 79 | 99 | ## Conventional Commits | |
@@ -237,8 +257,8 @@ Co-authored-by: Name <email> | |||
| 237 | 257 | ## Pull request checklist | |
| 238 | 258 | ||
| 239 | 259 | - PR title: Conventional Commits format (CI-enforced by `pr-lint.yml`). | |
| 240 | - - Tests: added/updated; `pytest` passes. | ||
| 241 | - - Lint/format: `ruff check .`, `black` pass. | ||
| 260 | + - Tests: added/updated; `uv run pytest` passes. | ||
| 261 | + - Lint/format: `uv run ruff check .` and `uv run black --check src examples tests` pass. | ||
| 242 | 262 | - Docs: update `README.md` if behavior changes. | |
| 243 | 263 | - Templates: update `src/pythonnative/templates/` if generator output changes. | |
| 244 | 264 | - No generated artifacts committed. | |
@@ -302,17 +322,17 @@ Build and run everything via the convenience script: | |||
| 302 | 322 | ||
| 303 | 323 | ```bash | |
| 304 | 324 | # Android (emulator must be running) | |
| 305 | - ./scripts/run-e2e.sh android | ||
| 325 | + uv run ./scripts/run-e2e.sh android | ||
| 306 | 326 | ||
| 307 | 327 | # iOS (simulator must be running) | |
| 308 | - ./scripts/run-e2e.sh ios | ||
| 328 | + uv run ./scripts/run-e2e.sh ios | ||
| 309 | 329 | ``` | |
| 310 | 330 | ||
| 311 | 331 | For tight iteration, run a single category instead of the full pass: | |
| 312 | 332 | ||
| 313 | 333 | ```bash | |
| 314 | - ./scripts/run-e2e.sh android hooks | ||
| 315 | - ./scripts/run-e2e.sh ios components | ||
| 334 | + uv run ./scripts/run-e2e.sh android hooks | ||
| 335 | + uv run ./scripts/run-e2e.sh ios components | ||
| 316 | 336 | ``` | |
| 317 | 337 | ||
| 318 | 338 | Available categories: `components`, `hooks`, `navigation`, `layout`, `styling`, `animations`, `misc`. | |
@@ -325,7 +345,7 @@ When you add a new public symbol you must also: | |||
| 325 | 345 | 2. Append a `DemoEntry` in `examples/e2e-suite/app/registry.py`. | |
| 326 | 346 | 3. Add a Maestro flow at `tests/e2e/flows/<category>/<name>.yaml`. | |
| 327 | 347 | 4. Append the flow to the top-level `tests/e2e/android.yaml`, `tests/e2e/ios.yaml`, and the matching `tests/e2e/suites/<category>.yaml`. | |
| 328 | - 5. Confirm `python scripts/check-e2e-coverage.py` exits 0. | ||
| 348 | + 5. Confirm `uv run python scripts/check-e2e-coverage.py` exits 0. | ||
| 329 | 349 | ||
| 330 | 350 | `tests/e2e/AGENTS.md` is the deeper reference (label conventions, failure triage, naming rules); AI agents should read it before touching the suite. The `e2e.yml` workflow runs the suite automatically on pushes to `main` and PRs. | |
| 331 | 351 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -35,28 +35,28 @@ ios = [ | |||
| 35 | 35 | build = [ | |
| 36 | 36 | "Pillow>=10.0", | |
| 37 | 37 | ] | |
| 38 | - docs = [ | ||
| 39 | - "mkdocs>=1.5", | ||
| 40 | - "mkdocs-material[imaging]>=9.5", | ||
| 41 | - "mkdocstrings[python]>=0.24", | ||
| 42 | - "mkdocs-autorefs>=1.0", | ||
| 43 | - "pymdown-extensions>=10.7", | ||
| 44 | - ] | ||
| 38 | + | ||
| 39 | + # Contributor tooling, not published as package extras (PEP 735). Install | ||
| 40 | + # with `uv sync --group dev` or `--group docs`; `uv sync` alone gets `dev`. | ||
| 41 | + [dependency-groups] | ||
| 45 | 42 | dev = [ | |
| 46 | 43 | "black>=24.0", | |
| 47 | 44 | "ruff>=0.5", | |
| 48 | 45 | "mypy>=1.10", | |
| 49 | 46 | "pytest>=8.0", | |
| 50 | 47 | "pytest-asyncio>=0.23", | |
| 51 | 48 | "Pillow>=10.0", | |
| 49 | + # `pn run ios` shells out to `sys.executable -m pip` to vendor | ||
| 50 | + # rubicon-objc (project/builder.py), and the test suite exercises that | ||
| 51 | + # path. `uv sync` does not seed pip the way `uv venv --seed` did. | ||
| 52 | + "pip>=24.0", | ||
| 52 | 53 | ] | |
| 53 | - ci = [ | ||
| 54 | - "black>=24.0", | ||
| 55 | - "ruff>=0.5", | ||
| 56 | - "mypy>=1.10", | ||
| 57 | - "pytest>=8.0", | ||
| 58 | - "pytest-asyncio>=0.23", | ||
| 59 | - "Pillow>=10.0", | ||
| 54 | + docs = [ | ||
| 55 | + "mkdocs>=1.5", | ||
| 56 | + "mkdocs-material[imaging]>=9.5", | ||
| 57 | + "mkdocstrings[python]>=0.24", | ||
| 58 | + "mkdocs-autorefs>=1.0", | ||
| 59 | + "pymdown-extensions>=10.7", | ||
| 60 | 60 | ] | |
| 61 | 61 | ||
| 62 | 62 | [project.scripts] | |
@@ -144,6 +144,15 @@ asyncio_mode = "auto" | |||
| 144 | 144 | # ── Semantic Release ──────────────────────────────────────────────── | |
| 145 | 145 | ||
| 146 | 146 | [tool.semantic_release] | |
| 147 | + # PSR stamps the new version into pyproject.toml before running this, so | ||
| 148 | + # `--upgrade-package` re-syncs only this project's own version in the lock | ||
| 149 | + # (never dependency upgrades), and the staged uv.lock lands in the release | ||
| 150 | + # commit. This also replaces the workflow's separate `python -m build`. | ||
| 151 | + build_command = """ | ||
| 152 | + uv lock --upgrade-package pythonnative | ||
| 153 | + git add uv.lock | ||
| 154 | + uv build | ||
| 155 | + """ | ||
| 147 | 156 | version_toml = ["pyproject.toml:project.version"] | |
| 148 | 157 | version_variables = ["src/pythonnative/__init__.py:__version__"] | |
| 149 | 158 | commit_message = "chore(release): v{version}" | |
| Back | FazBrowse Home | New Git URL |
0 commit comments