chore(deps): bump patchright from 1.62.2 to 1.63.0 #180
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: ci | |
| on: | |
| pull_request: | |
| push: | |
| branches: [main] | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ci-${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| PYTHONUNBUFFERED: "1" | |
| PIP_DISABLE_PIP_VERSION_CHECK: "1" | |
| # This workflow executes pull-request code. Every job must remain on an | |
| # ephemeral GitHub-hosted runner; tests/test_workflow_shape.py enforces that | |
| # boundary across every pull_request-triggered workflow in the repository. | |
| jobs: | |
| change-map: | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 5 | |
| steps: | |
| - name: Checkout exact commit | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| fetch-depth: 0 | |
| persist-credentials: false | |
| - name: Record deterministic change map | |
| shell: bash | |
| env: | |
| BASE_SHA: ${{ github.event.pull_request.base.sha || github.event.before }} | |
| run: | | |
| if git cat-file -e "${BASE_SHA}^{commit}" 2>/dev/null; then | |
| git diff --name-only "${BASE_SHA}...${GITHUB_SHA}" | sort -u > changed-paths.txt | |
| else | |
| git show --pretty='' --name-only "${GITHUB_SHA}" | sort -u > changed-paths.txt | |
| fi | |
| python - <<'PY' | |
| import json | |
| import os | |
| from pathlib import Path | |
| paths = [line for line in Path("changed-paths.txt").read_text().splitlines() if line] | |
| classes = { | |
| "code": any( | |
| path.startswith(("src/", "tests/")) or path == "pyproject.toml" | |
| for path in paths | |
| ), | |
| "container": any( | |
| path in {"Dockerfile", "docker-compose.yml"} | |
| or path.startswith("scripts/") | |
| for path in paths | |
| ), | |
| "public_copy": any( | |
| path == "README.md" | |
| or path.startswith(("docs/", "assets/", "examples/")) | |
| for path in paths | |
| ), | |
| "workflow": any( | |
| path.startswith(".github/") or path == ".aether-ci.yml" | |
| for path in paths | |
| ), | |
| } | |
| with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as output: | |
| for name, selected in classes.items(): | |
| output.write(f"{name}={str(selected).lower()}\n") | |
| print( | |
| json.dumps( | |
| {"sha": os.environ["GITHUB_SHA"], "paths": paths, "classes": classes}, | |
| sort_keys=True, | |
| ) | |
| ) | |
| PY | |
| quality: | |
| needs: change-map | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 12 | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 | |
| with: | |
| python-version: "3.11" | |
| - name: Install locked dependencies | |
| run: >- | |
| python -m pip install --require-hashes -r requirements.lock && | |
| python -m pip install --no-build-isolation --no-deps -e . | |
| - name: Format | |
| run: python -m ruff format --check . | |
| - name: Lint | |
| run: python -m ruff check . | |
| - name: Type check | |
| run: python -m mypy src | |
| - name: Manifest validation | |
| run: python scripts/verify_release.py --manifest-only | |
| unit: | |
| needs: change-map | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 15 | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 | |
| with: | |
| python-version: "3.11" | |
| - name: Install locked dependencies | |
| run: >- | |
| python -m pip install --require-hashes -r requirements.lock && | |
| python -m pip install --no-build-isolation --no-deps -e . | |
| - run: python -m pytest -q | |
| security: | |
| needs: change-map | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 15 | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 | |
| with: | |
| python-version: "3.11" | |
| - name: Install locked dependencies | |
| run: >- | |
| python -m pip install --require-hashes -r requirements.lock && | |
| python -m pip install --no-build-isolation --no-deps -e . | |
| - run: python scripts/verify_release.py --security-only | |
| - run: python -m bandit -q -r src | |
| - run: python -m pip_audit --strict --disable-pip -r requirements.lock | |
| - run: >- | |
| python -m pytest -q tests/test_auth.py tests/test_policy.py | |
| tests/test_security.py tests/test_workflow_shape.py | |
| - run: python -m pip check | |
| node-client: | |
| needs: change-map | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 10 | |
| defaults: | |
| run: | |
| working-directory: clients/node | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 | |
| with: | |
| node-version: "20" | |
| - name: Refuse runtime dependencies | |
| shell: bash | |
| run: | | |
| set -Eeuo pipefail | |
| deps="$(node -p "JSON.stringify(require('./package.json').dependencies || {})")" | |
| test "$deps" = "{}" | |
| - name: Unit tests | |
| # Explicit paths rather than a glob: Node only gained glob expansion for | |
| # --test in v22, and this job must keep working on the oldest supported runtime. | |
| run: npm test | |
| - name: Type declarations match the implementation | |
| run: | | |
| npm install --no-save --no-audit --no-fund typescript@5.9.3 | |
| npx tsc --noEmit -p tsconfig.json | |
| - name: Packaging is complete and free of stray files | |
| shell: bash | |
| run: | | |
| set -Eeuo pipefail | |
| npm pack --dry-run --json > /tmp/pack.json | |
| node -e ' | |
| const [pack] = require("/tmp/pack.json"); | |
| const files = pack.files.map((f) => f.path).sort(); | |
| const required = ["package.json", "README.md", "LICENSE", "src/index.js", "src/index.d.ts", "src/cli.js"]; | |
| for (const name of required) { | |
| if (!files.includes(name)) throw new Error(`missing from tarball: ${name}`); | |
| } | |
| const stray = files.filter((f) => f.startsWith("test/") || f.endsWith("tsconfig.json")); | |
| if (stray.length) throw new Error(`tests must not ship: ${stray.join(", ")}`); | |
| console.log(`tarball: ${files.length} files, ${pack.size} bytes`); | |
| ' | |
| - name: CLI runs without a server present | |
| run: node src/cli.js --version && node src/cli.js help | |
| python-client: | |
| needs: change-map | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 10 | |
| defaults: | |
| run: | |
| working-directory: clients/python | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 | |
| with: | |
| # The floor declared by requires-python, so the published wheel is proved on the | |
| # oldest interpreter it claims to support rather than only on a modern one. | |
| python-version: "3.10" | |
| - name: Refuse runtime dependencies | |
| run: grep -qx 'dependencies = \[\]' pyproject.toml | |
| - name: Unit tests | |
| # tests/test_packaging.py reads clients/node/package.json, so a version or command | |
| # that drifts between the two clients fails here rather than on PyPI. | |
| env: | |
| PYTHONPATH: src | |
| run: python -m unittest discover -s tests -v | |
| - name: Type check | |
| run: | | |
| python -m pip install --disable-pip-version-check mypy==2.3.1 | |
| python -m mypy src | |
| - name: Packaging is complete and free of stray files | |
| run: | | |
| set -Eeuo pipefail | |
| python -m pip install --disable-pip-version-check build==1.4.0 twine==6.2.0 | |
| python -m build | |
| python -m twine check --strict dist/* | |
| python - <<'PY' | |
| import pathlib | |
| import zipfile | |
| wheel = next(pathlib.Path("dist").glob("*.whl")) | |
| names = sorted(zipfile.ZipFile(wheel).namelist()) | |
| required = [ | |
| "aether_browser/__init__.py", | |
| "aether_browser/_client.py", | |
| "aether_browser/cli.py", | |
| "aether_browser/py.typed", | |
| ] | |
| for name in required: | |
| assert name in names, f"missing from wheel: {name}" | |
| stray = [name for name in names if name.startswith("tests/")] | |
| assert not stray, f"tests must not ship: {stray}" | |
| print(f"wheel: {len(names)} entries") | |
| PY | |
| - name: CLI runs without a server present | |
| env: | |
| PYTHONPATH: src | |
| run: python -m aether_browser.cli --version && python -m aether_browser.cli help |