|
7 | 7 | branches: [ main, master ] |
8 | 8 | pull_request: |
9 | 9 | workflow_dispatch: |
| 10 | + inputs: |
| 11 | + run_integration: |
| 12 | + description: "Run integration tests (live network/browser)" |
| 13 | + required: false |
| 14 | + default: false |
| 15 | + type: boolean |
10 | 16 |
|
11 | 17 | concurrency: |
12 | 18 | group: ${{ github.workflow }}-${{ github.ref }} |
@@ -50,12 +56,14 @@ jobs: |
50 | 56 | - name: Ruff lint |
51 | 57 | run: ruff check src |
52 | 58 |
|
53 | | - # - name: Mypy type-check |
54 | | - # run: mypy src/web_scraper_toolkit |
55 | | - # continue-on-error: true # Strict typing is a work in progress |
| 59 | + - name: Mypy type-check |
| 60 | + run: mypy |
56 | 61 |
|
57 | 62 | - name: Run tests |
58 | | - run: pytest -q |
| 63 | + run: pytest -q -m "not integration" |
| 64 | + |
| 65 | + - name: Workspace hygiene dry run |
| 66 | + run: python scripts/clean_workspace.py --dry-run |
59 | 67 |
|
60 | 68 | - name: Build sdist and wheel |
61 | 69 | run: python -m build |
|
67 | 75 | run: | |
68 | 76 | python -m pip install --force-reinstall dist/*.whl |
69 | 77 | python -c "import web_scraper_toolkit, subprocess, sys; print('Toolkit version:', getattr(web_scraper_toolkit, '__version__', 'unknown')); subprocess.run(['web-scraper', '--help'], check=True)" |
| 78 | +
|
| 79 | + security: |
| 80 | + name: security gates |
| 81 | + runs-on: ubuntu-latest |
| 82 | + env: |
| 83 | + PIP_DISABLE_PIP_VERSION_CHECK: "1" |
| 84 | + steps: |
| 85 | + - name: Checkout |
| 86 | + uses: actions/checkout@v4 |
| 87 | + |
| 88 | + - name: Set up Python 3.12 |
| 89 | + uses: actions/setup-python@v5 |
| 90 | + with: |
| 91 | + python-version: "3.12" |
| 92 | + cache: "pip" |
| 93 | + |
| 94 | + - name: Upgrade pip |
| 95 | + run: python -m pip install -U pip |
| 96 | + |
| 97 | + - name: Install security tooling |
| 98 | + run: python -m pip install -U bandit pip-audit |
| 99 | + |
| 100 | + - name: Run Bandit (high severity only) |
| 101 | + run: python -m bandit -q -r src/web_scraper_toolkit -lll -iii |
| 102 | + |
| 103 | + - name: Build dependency audit requirements |
| 104 | + run: | |
| 105 | + python - <<'PY' |
| 106 | + import pathlib |
| 107 | + import tomllib |
| 108 | +
|
| 109 | + pyproject = pathlib.Path("pyproject.toml") |
| 110 | + data = tomllib.loads(pyproject.read_text(encoding="utf-8")) |
| 111 | + deps = list(data.get("project", {}).get("dependencies", [])) |
| 112 | + out = pathlib.Path(".audit-requirements.txt") |
| 113 | + out.write_text("\n".join(deps) + "\n", encoding="utf-8") |
| 114 | + print(out.read_text(encoding="utf-8")) |
| 115 | + PY |
| 116 | +
|
| 117 | + - name: Run pip-audit |
| 118 | + run: python -m pip_audit -r .audit-requirements.txt --strict |
| 119 | + |
| 120 | + - name: Run Gitleaks secret scan |
| 121 | + uses: gitleaks/gitleaks-action@v2 |
| 122 | + env: |
| 123 | + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| 124 | + |
| 125 | + integration: |
| 126 | + name: integration tests (manual) |
| 127 | + if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.run_integration == 'true' }} |
| 128 | + runs-on: ubuntu-latest |
| 129 | + env: |
| 130 | + PIP_DISABLE_PIP_VERSION_CHECK: "1" |
| 131 | + SKIP_CF_TEST: "0" |
| 132 | + steps: |
| 133 | + - name: Checkout |
| 134 | + uses: actions/checkout@v4 |
| 135 | + |
| 136 | + - name: Set up Python 3.12 |
| 137 | + uses: actions/setup-python@v5 |
| 138 | + with: |
| 139 | + python-version: "3.12" |
| 140 | + cache: "pip" |
| 141 | + |
| 142 | + - name: Upgrade pip |
| 143 | + run: python -m pip install -U pip |
| 144 | + |
| 145 | + - name: Install project and test tooling |
| 146 | + run: | |
| 147 | + python -m pip install -e . |
| 148 | + python -m pip install -U pytest pytest-asyncio |
| 149 | +
|
| 150 | + - name: Install Playwright browsers |
| 151 | + run: playwright install --with-deps chromium |
| 152 | + |
| 153 | + - name: Run integration tests |
| 154 | + run: pytest -q -m integration |
0 commit comments