docs: link the CLI mention to the command reference #12
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: wheels | |
| # Build one py3-none wheel per platform by bundling the official binary from | |
| # the browser repo's GitHub release (the same asset the README tells users to | |
| # download). No compilation happens here — all four wheels build on one | |
| # Ubuntu runner; native runners are only needed to *test* them. | |
| # | |
| # Modeled on zignal's python.yml (matrix -> build -> test-the-wheel -> | |
| # publish), minus everything a C extension needs: no per-Python builds, | |
| # no cross-compilation, no auditwheel/delocate. | |
| # | |
| # Triggers: | |
| # - pull_request / push to main: build + test against the browser | |
| # `nightly` release, no publish. | |
| # - release published: build + test the browser release with the SAME tag | |
| # and publish to PyPI. A release tag on this repo must equal the browser | |
| # release tag it ships (e.g. 0.4.0); the wheel version is derived from | |
| # it. Releases here are created automatically by the browser repo's | |
| # release workflow (its `update-python-package` job) whenever it builds a | |
| # version tag, so a browser release flows to PyPI with no polling — the | |
| # publish still stops at the pypi environment's required-reviewer gate. | |
| # - workflow_dispatch: pick any browser tag and publish target manually. | |
| on: | |
| pull_request: | |
| push: | |
| branches: [main] | |
| release: | |
| types: [published] | |
| workflow_dispatch: | |
| inputs: | |
| release: | |
| description: "browser release tag to bundle (nightly or a version tag)" | |
| default: "nightly" | |
| publish: | |
| description: "where to publish" | |
| type: choice | |
| options: [none, testpypi, pypi] | |
| default: none | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| BROWSER_REPO: lightpanda-io/browser | |
| jobs: | |
| # Map the triggering event to the browser tag to bundle and the publish | |
| # target, so the downstream jobs don't each re-derive it. | |
| params: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| outputs: | |
| release_tag: ${{ steps.resolve.outputs.release_tag }} | |
| publish: ${{ steps.resolve.outputs.publish }} | |
| steps: | |
| - name: Resolve release tag and publish target | |
| id: resolve | |
| run: | | |
| case "${{ github.event_name }}" in | |
| release) | |
| echo "release_tag=${{ github.event.release.tag_name }}" >> "$GITHUB_OUTPUT" | |
| echo "publish=pypi" >> "$GITHUB_OUTPUT" | |
| ;; | |
| workflow_dispatch) | |
| echo "release_tag=${{ inputs.release }}" >> "$GITHUB_OUTPUT" | |
| echo "publish=${{ inputs.publish }}" >> "$GITHUB_OUTPUT" | |
| ;; | |
| *) | |
| echo "release_tag=nightly" >> "$GITHUB_OUTPUT" | |
| echo "publish=none" >> "$GITHUB_OUTPUT" | |
| ;; | |
| esac | |
| cat "$GITHUB_OUTPUT" | |
| # A nightly build keeps pyproject's dev version; never let one | |
| # reach PyPI, whatever dispatched it. | |
| if grep -q '^publish=pypi$' "$GITHUB_OUTPUT" && grep -q '^release_tag=nightly$' "$GITHUB_OUTPUT"; then | |
| echo "::error::refusing to publish a nightly build to PyPI (pick a version tag)" | |
| exit 1 | |
| fi | |
| build: | |
| needs: params | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| strategy: | |
| matrix: | |
| include: | |
| - asset: lightpanda-x86_64-linux | |
| plat: manylinux_2_35_x86_64 | |
| - asset: lightpanda-aarch64-linux | |
| plat: manylinux_2_35_aarch64 | |
| - asset: lightpanda-aarch64-macos | |
| plat: macosx_14_0_arm64 | |
| - asset: lightpanda-x86_64-macos | |
| plat: macosx_13_0_x86_64 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: astral-sh/setup-uv@v5 | |
| - name: Download the release binary | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| gh release download "${{ needs.params.outputs.release_tag }}" -R "$BROWSER_REPO" \ | |
| -p "${{ matrix.asset }}" -O lightpanda-bin | |
| chmod +x lightpanda-bin | |
| ls -la lightpanda-bin | |
| # The tool schemas are platform-independent; fetch the one binary | |
| # this runner can execute to regenerate the methods from. | |
| if [ "${{ matrix.asset }}" = lightpanda-x86_64-linux ]; then | |
| cp lightpanda-bin lightpanda-gen | |
| else | |
| gh release download "${{ needs.params.outputs.release_tag }}" -R "$BROWSER_REPO" \ | |
| -p lightpanda-x86_64-linux -O lightpanda-gen | |
| chmod +x lightpanda-gen | |
| fi | |
| - name: Regenerate tool methods from the bundled binary | |
| env: | |
| LIGHTPANDA_BIN: ${{ github.workspace }}/lightpanda-gen | |
| run: | | |
| # The wheel always ships methods matching the binary it bundles. | |
| uv run --no-project python scripts/generate_methods.py | |
| # PRs and pushes build against nightly: fail on drift so the committed | |
| # file (what IDEs and the docs see) keeps up with the browser's tools. | |
| case "${{ github.event_name }}" in | |
| pull_request|push) | |
| git diff --exit-code -- lightpanda/_methods.py || { | |
| echo "::error::lightpanda/_methods.py is out of date: run scripts/generate_methods.py and commit the result" | |
| exit 1 | |
| } | |
| ;; | |
| esac | |
| - name: Set wheel version from tag | |
| if: needs.params.outputs.release_tag != 'nightly' | |
| run: | | |
| # Wheel version == browser release tag (PEP 440 expects no leading v). | |
| tag="${{ needs.params.outputs.release_tag }}" | |
| sed -i "s/^version = .*/version = \"${tag#v}\"/" pyproject.toml | |
| grep '^version' pyproject.toml | |
| - name: Build wheel | |
| env: | |
| LIGHTPANDA_BIN: ${{ github.workspace }}/lightpanda-bin | |
| LIGHTPANDA_PLAT: ${{ matrix.plat }} | |
| run: uv build --wheel | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: wheel-${{ matrix.plat }} | |
| path: dist/*.whl | |
| test: | |
| needs: build | |
| timeout-minutes: 15 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - runner: ubuntu-latest | |
| plat: manylinux_2_35_x86_64 | |
| - runner: ubuntu-24.04-arm | |
| plat: manylinux_2_35_aarch64 | |
| - runner: macos-14 | |
| plat: macosx_14_0_arm64 | |
| - runner: macos-15-intel | |
| plat: macosx_13_0_x86_64 | |
| runs-on: ${{ matrix.runner }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: astral-sh/setup-uv@v5 | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: wheel-${{ matrix.plat }} | |
| path: dist | |
| - name: Install the wheel into a clean venv | |
| run: | | |
| uv venv wheel-env | |
| uv pip install --python wheel-env dist/*.whl pytest pytest-asyncio | |
| - name: Run the test suite against the installed wheel | |
| run: | | |
| # Resolve the *bundled* binary and pin the tests to it; run from | |
| # outside the checkout so the source tree can't shadow the install | |
| # (-I likewise keeps the cwd off sys.path for this resolution). | |
| # pyproject.toml comes along for its [tool.pytest.ini_options] | |
| # (asyncio_mode) — without it the async tests are silently skipped. | |
| BIN=$(./wheel-env/bin/python -I -c "from lightpanda.client import find_binary; print(find_binary())") | |
| echo "bundled binary: $BIN" | |
| mkdir -p /tmp/wheeltest && cp -r tests pyproject.toml /tmp/wheeltest/ | |
| cd /tmp/wheeltest | |
| LIGHTPANDA_BIN="$BIN" "$GITHUB_WORKSPACE"/wheel-env/bin/python -m pytest tests -q | |
| - name: CLI smoke | |
| run: ./wheel-env/bin/lightpanda version | |
| publish: | |
| needs: [params, test] | |
| if: needs.params.outputs.publish != 'none' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| environment: ${{ needs.params.outputs.publish }} | |
| permissions: | |
| id-token: write # PyPI trusted publishing | |
| steps: | |
| - uses: astral-sh/setup-uv@v5 | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| pattern: wheel-* | |
| merge-multiple: true | |
| path: dist | |
| - name: Publish | |
| run: | | |
| if [ "${{ needs.params.outputs.publish }}" = "testpypi" ]; then | |
| uv publish --publish-url https://test.pypi.org/legacy/ dist/*.whl | |
| else | |
| uv publish dist/*.whl | |
| fi |