chore: import upstream snapshot with attribution
Tests / tests (map[TOXENV:py310], macos-latest, 3.10) (push) Has been cancelled
Tests / tests (map[TOXENV:py311], macos-latest, 3.11) (push) Has been cancelled
Tests / tests (map[TOXENV:py312], macos-latest, 3.12) (push) Has been cancelled
Tests / tests (map[TOXENV:py313], macos-latest, 3.13) (push) Has been cancelled
Tests / tests (map[TOXENV:py310], macos-latest, 3.10) (push) Has been cancelled
Tests / tests (map[TOXENV:py311], macos-latest, 3.11) (push) Has been cancelled
Tests / tests (map[TOXENV:py312], macos-latest, 3.12) (push) Has been cancelled
Tests / tests (map[TOXENV:py313], macos-latest, 3.13) (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
github: D4Vinci
|
||||
buy_me_a_coffee: d4vinci
|
||||
ko_fi: d4vinci
|
||||
@@ -0,0 +1,82 @@
|
||||
name: Bug report
|
||||
description: Create a bug report to help us address errors in the repository
|
||||
labels: [bug]
|
||||
body:
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Have you searched if there an existing issue for this?
|
||||
description: Please search [existing issues](https://github.com/D4Vinci/Scrapling/labels/bug).
|
||||
options:
|
||||
- label: I have searched the existing issues
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
attributes:
|
||||
label: "Python version (python --version)"
|
||||
placeholder: "Python 3.8"
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
attributes:
|
||||
label: "Scrapling version (scrapling.__version__)"
|
||||
placeholder: "0.1"
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: "Dependencies version (pip3 freeze)"
|
||||
description: >
|
||||
This is the output of the command `pip3 freeze --all`. Note that the
|
||||
actual output might be different as compared to the placeholder text.
|
||||
placeholder: |
|
||||
cssselect==1.2.0
|
||||
lxml==5.3.0
|
||||
orjson==3.10.7
|
||||
...
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
attributes:
|
||||
label: "What's your operating system?"
|
||||
placeholder: "Windows 10"
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: 'Are you using a separate virtual environment?'
|
||||
description: "Please pay attention to this question"
|
||||
options:
|
||||
- 'No'
|
||||
- 'Yes'
|
||||
default: 0
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: "Expected behavior"
|
||||
description: "Describe the behavior you expect. May include images or videos."
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: "Actual behavior"
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Steps To Reproduce
|
||||
description: Steps to reproduce the behavior.
|
||||
placeholder: |
|
||||
1. In this environment...
|
||||
2. With this config...
|
||||
3. Run '...'
|
||||
4. See error...
|
||||
validations:
|
||||
required: false
|
||||
@@ -0,0 +1,19 @@
|
||||
name: Feature request
|
||||
description: Suggest features, propose improvements, discuss new ideas.
|
||||
labels: [enhancement]
|
||||
body:
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Have you searched if there an existing feature request for this?
|
||||
description: Please search [existing requests](https://github.com/D4Vinci/Scrapling/labels/enhancement).
|
||||
options:
|
||||
- label: I have searched the existing requests
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: "Feature description"
|
||||
description: >
|
||||
This could include new topics or improving any existing features/implementations.
|
||||
validations:
|
||||
required: true
|
||||
@@ -0,0 +1,19 @@
|
||||
name: Other
|
||||
description: Use this for any other issues. PLEASE provide as much information as possible.
|
||||
labels: ["awaiting triage"]
|
||||
body:
|
||||
- type: textarea
|
||||
id: issuedescription
|
||||
attributes:
|
||||
label: What would you like to share?
|
||||
description: Provide a clear and concise explanation of your issue.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: extrainfo
|
||||
attributes:
|
||||
label: Additional information
|
||||
description: Is there anything else we should know about this issue?
|
||||
validations:
|
||||
required: false
|
||||
@@ -0,0 +1,40 @@
|
||||
name: Documentation issue
|
||||
description: Report incorrect, unclear, or missing documentation.
|
||||
labels: [documentation]
|
||||
body:
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Have you searched if there an existing issue for this?
|
||||
description: Please search [existing issues](https://github.com/D4Vinci/Scrapling/labels/documentation).
|
||||
options:
|
||||
- label: I have searched the existing issues
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
attributes:
|
||||
label: "Page URL"
|
||||
description: "Link to the documentation page with the issue."
|
||||
placeholder: "https://scrapling.readthedocs.io/en/latest/..."
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: "Type of issue"
|
||||
options:
|
||||
- Incorrect information
|
||||
- Unclear or confusing
|
||||
- Missing information
|
||||
- Typo or formatting
|
||||
- Broken link
|
||||
- Other
|
||||
default: 0
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: "Description"
|
||||
description: "Describe what's wrong and what you expected to find."
|
||||
validations:
|
||||
required: true
|
||||
@@ -0,0 +1,10 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Discussions
|
||||
url: https://github.com/D4Vinci/Scrapling/discussions
|
||||
about: >
|
||||
The "Discussions" forum is where you want to start. 💖
|
||||
- name: Ask on our discord server
|
||||
url: https://discord.gg/EMgGbDceNQ
|
||||
about: >
|
||||
Our community chat forum.
|
||||
@@ -0,0 +1,51 @@
|
||||
<!--
|
||||
You are amazing! Thanks for contributing to Scrapling!
|
||||
Please, DO NOT DELETE ANY TEXT from this template! (unless instructed).
|
||||
-->
|
||||
|
||||
## Proposed change
|
||||
<!--
|
||||
Describe the big picture of your changes here to communicate to the maintainers why we should accept this pull request.
|
||||
If it fixes a bug or resolves a feature request, be sure to link to that issue in the additional information section.
|
||||
-->
|
||||
|
||||
|
||||
### Type of change:
|
||||
<!--
|
||||
What type of change does your PR introduce to Scrapling?
|
||||
NOTE: Please, check at least 1 box!
|
||||
If your PR requires multiple boxes to be checked, you'll most likely need to
|
||||
split it into multiple PRs. This makes things easier and faster to code review.
|
||||
-->
|
||||
|
||||
|
||||
|
||||
- [ ] Dependency upgrade
|
||||
- [ ] Bugfix (non-breaking change which fixes an issue)
|
||||
- [ ] New integration (thank you!)
|
||||
- [ ] New feature (which adds functionality to an existing integration)
|
||||
- [ ] Deprecation (breaking change to happen in the future)
|
||||
- [ ] Breaking change (fix/feature causing existing functionality to break)
|
||||
- [ ] Code quality improvements to existing code or addition of tests
|
||||
- [ ] Add or change doctests? -- Note: Please avoid changing both code and tests in a single pull request.
|
||||
- [ ] Documentation change?
|
||||
|
||||
### Additional information
|
||||
<!--
|
||||
Details are important and help maintainers processing your PR.
|
||||
Please be sure to fill out additional details, if applicable.
|
||||
-->
|
||||
|
||||
- This PR fixes or closes an issue: fixes #
|
||||
- This PR is related to an issue: #
|
||||
- Link to documentation pull request: **
|
||||
|
||||
### Checklist:
|
||||
* [ ] I have read [CONTRIBUTING.md](https://github.com/D4Vinci/Scrapling/blob/main/CONTRIBUTING.md).
|
||||
* [ ] This pull request is all my own work -- I have not plagiarized.
|
||||
* [ ] I know that pull requests will not be merged if they fail the automated tests.
|
||||
* [ ] All new Python files are placed inside an existing directory.
|
||||
* [ ] All filenames are in all lowercase characters with no spaces or dashes.
|
||||
* [ ] All functions and variable names follow Python naming conventions.
|
||||
* [ ] All function parameters and return values are annotated with Python [type hints](https://docs.python.org/3/library/typing.html).
|
||||
* [ ] All functions have doc-strings.
|
||||
@@ -0,0 +1,190 @@
|
||||
name: Code Quality
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- dev
|
||||
paths-ignore:
|
||||
- '*.md'
|
||||
- '**/*.md'
|
||||
- 'docs/**'
|
||||
- 'images/**'
|
||||
- '.github/**'
|
||||
- 'agent-skill/**'
|
||||
- '!.github/workflows/code-quality.yml' # Always run when this workflow changes
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
- dev
|
||||
paths-ignore:
|
||||
- '*.md'
|
||||
- '**/*.md'
|
||||
- 'docs/**'
|
||||
- 'images/**'
|
||||
- '.github/**'
|
||||
- 'agent-skill/**'
|
||||
- '*.yml'
|
||||
- '*.yaml'
|
||||
- 'ruff.toml'
|
||||
workflow_dispatch: # Allow manual triggering
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
code-quality:
|
||||
name: Code Quality Checks
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write # For PR annotations
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0 # Full history for better analysis
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: '3.10'
|
||||
cache: 'pip'
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install bandit[toml] ruff vermin mypy pyright
|
||||
pip install -e ".[all]"
|
||||
pip install lxml-stubs scrapy
|
||||
|
||||
- name: Run Bandit (Security Linter)
|
||||
id: bandit
|
||||
continue-on-error: true
|
||||
run: |
|
||||
echo "::group::Bandit - Security Linter"
|
||||
bandit -r -c .bandit.yml scrapling/ -f json -o bandit-report.json
|
||||
bandit -r -c .bandit.yml scrapling/
|
||||
echo "::endgroup::"
|
||||
|
||||
- name: Run Ruff Linter
|
||||
id: ruff-lint
|
||||
continue-on-error: true
|
||||
run: |
|
||||
echo "::group::Ruff - Linter"
|
||||
ruff check scrapling/ --output-format=github
|
||||
echo "::endgroup::"
|
||||
|
||||
- name: Run Ruff Formatter Check
|
||||
id: ruff-format
|
||||
continue-on-error: true
|
||||
run: |
|
||||
echo "::group::Ruff - Formatter Check"
|
||||
ruff format --check scrapling/ --diff
|
||||
echo "::endgroup::"
|
||||
|
||||
- name: Run Vermin (Python Version Compatibility)
|
||||
id: vermin
|
||||
continue-on-error: true
|
||||
run: |
|
||||
echo "::group::Vermin - Python 3.10+ Compatibility Check"
|
||||
vermin -t=3.10- --violations --eval-annotations --no-tips scrapling/
|
||||
echo "::endgroup::"
|
||||
|
||||
- name: Run Mypy (Static Type Checker)
|
||||
id: mypy
|
||||
continue-on-error: true
|
||||
run: |
|
||||
echo "::group::Mypy - Static Type Checker"
|
||||
mypy scrapling/
|
||||
echo "::endgroup::"
|
||||
|
||||
- name: Run Pyright (Static Type Checker)
|
||||
id: pyright
|
||||
continue-on-error: true
|
||||
run: |
|
||||
echo "::group::Pyright - Static Type Checker"
|
||||
pyright scrapling/
|
||||
echo "::endgroup::"
|
||||
|
||||
- name: Check results and create summary
|
||||
if: always()
|
||||
run: |
|
||||
echo "# Code Quality Check Results" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
# Initialize status
|
||||
all_passed=true
|
||||
|
||||
# Check Bandit
|
||||
if [ "${{ steps.bandit.outcome }}" == "success" ]; then
|
||||
echo "✅ **Bandit (Security)**: Passed" >> $GITHUB_STEP_SUMMARY
|
||||
else
|
||||
echo "❌ **Bandit (Security)**: Failed" >> $GITHUB_STEP_SUMMARY
|
||||
all_passed=false
|
||||
fi
|
||||
|
||||
# Check Ruff Linter
|
||||
if [ "${{ steps.ruff-lint.outcome }}" == "success" ]; then
|
||||
echo "✅ **Ruff Linter**: Passed" >> $GITHUB_STEP_SUMMARY
|
||||
else
|
||||
echo "❌ **Ruff Linter**: Failed" >> $GITHUB_STEP_SUMMARY
|
||||
all_passed=false
|
||||
fi
|
||||
|
||||
# Check Ruff Formatter
|
||||
if [ "${{ steps.ruff-format.outcome }}" == "success" ]; then
|
||||
echo "✅ **Ruff Formatter**: Passed" >> $GITHUB_STEP_SUMMARY
|
||||
else
|
||||
echo "❌ **Ruff Formatter**: Failed" >> $GITHUB_STEP_SUMMARY
|
||||
all_passed=false
|
||||
fi
|
||||
|
||||
# Check Vermin
|
||||
if [ "${{ steps.vermin.outcome }}" == "success" ]; then
|
||||
echo "✅ **Vermin (Python 3.10+)**: Passed" >> $GITHUB_STEP_SUMMARY
|
||||
else
|
||||
echo "❌ **Vermin (Python 3.10+)**: Failed" >> $GITHUB_STEP_SUMMARY
|
||||
all_passed=false
|
||||
fi
|
||||
|
||||
# Check Mypy
|
||||
if [ "${{ steps.mypy.outcome }}" == "success" ]; then
|
||||
echo "✅ **Mypy (Type Checker)**: Passed" >> $GITHUB_STEP_SUMMARY
|
||||
else
|
||||
echo "❌ **Mypy (Type Checker)**: Failed" >> $GITHUB_STEP_SUMMARY
|
||||
all_passed=false
|
||||
fi
|
||||
|
||||
# Check Pyright
|
||||
if [ "${{ steps.pyright.outcome }}" == "success" ]; then
|
||||
echo "✅ **Pyright (Type Checker)**: Passed" >> $GITHUB_STEP_SUMMARY
|
||||
else
|
||||
echo "❌ **Pyright (Type Checker)**: Failed" >> $GITHUB_STEP_SUMMARY
|
||||
all_passed=false
|
||||
fi
|
||||
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
if [ "$all_passed" == "true" ]; then
|
||||
echo "### 🎉 All checks passed!" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "Your code meets all quality standards." >> $GITHUB_STEP_SUMMARY
|
||||
else
|
||||
echo "### ⚠️ Some checks failed" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "Please review the errors above and fix them." >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "**Tip**: Run \`pre-commit run --all-files\` locally to catch these issues before pushing." >> $GITHUB_STEP_SUMMARY
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Upload Bandit report
|
||||
if: always() && steps.bandit.outcome != 'skipped'
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: bandit-security-report
|
||||
path: bandit-report.json
|
||||
retention-days: 30
|
||||
@@ -0,0 +1,86 @@
|
||||
name: Build and Push Docker Image
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [closed]
|
||||
branches:
|
||||
- main
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tag:
|
||||
description: 'Docker image tag'
|
||||
required: true
|
||||
default: 'latest'
|
||||
|
||||
env:
|
||||
DOCKERHUB_IMAGE: pyd4vinci/scrapling
|
||||
GHCR_IMAGE: ghcr.io/${{ github.repository_owner }}/scrapling
|
||||
|
||||
jobs:
|
||||
build-and-push:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
with:
|
||||
platforms: linux/amd64,linux/arm64
|
||||
|
||||
- name: Log in to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: docker.io
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: Log in to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.CONTAINER_TOKEN }}
|
||||
|
||||
- name: Extract metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: |
|
||||
${{ env.DOCKERHUB_IMAGE }}
|
||||
${{ env.GHCR_IMAGE }}
|
||||
tags: |
|
||||
type=ref,event=branch
|
||||
type=ref,event=pr
|
||||
type=semver,pattern={{version}}
|
||||
type=semver,pattern={{major}}.{{minor}}
|
||||
type=semver,pattern={{major}}
|
||||
type=raw,value=latest,enable={{is_default_branch}}
|
||||
labels: |
|
||||
org.opencontainers.image.title=Scrapling
|
||||
org.opencontainers.image.description=An undetectable, powerful, flexible, high-performance Python library that makes Web Scraping easy and effortless as it should be!
|
||||
org.opencontainers.image.vendor=D4Vinci
|
||||
org.opencontainers.image.licenses=BSD
|
||||
org.opencontainers.image.url=https://scrapling.readthedocs.io/en/latest/
|
||||
org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}
|
||||
org.opencontainers.image.documentation=https://scrapling.readthedocs.io/en/latest/
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
build-args: |
|
||||
BUILDKIT_INLINE_CACHE=1
|
||||
|
||||
- name: Image digest
|
||||
run: echo ${{ steps.build.outputs.digest }}
|
||||
@@ -0,0 +1,74 @@
|
||||
name: Create Release and Publish to PyPI
|
||||
# Creates a GitHub release when a PR is merged to main (using PR title as version and body as release notes), then publishes to PyPI.
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [closed]
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
create-release-and-publish:
|
||||
if: github.event.pull_request.merged == true
|
||||
runs-on: ubuntu-latest
|
||||
environment:
|
||||
name: PyPI
|
||||
url: https://pypi.org/p/scrapling
|
||||
permissions:
|
||||
contents: write
|
||||
id-token: write
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Get PR title
|
||||
id: pr_title
|
||||
run: echo "title=${{ github.event.pull_request.title }}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Save PR body to file
|
||||
uses: actions/github-script@v8
|
||||
with:
|
||||
script: |
|
||||
const fs = require('fs');
|
||||
fs.writeFileSync('pr_body.md', context.payload.pull_request.body || '');
|
||||
|
||||
- name: Extract version
|
||||
id: extract_version
|
||||
run: |
|
||||
PR_TITLE="${{ steps.pr_title.outputs.title }}"
|
||||
if [[ $PR_TITLE =~ ^v ]]; then
|
||||
echo "version=$PR_TITLE" >> $GITHUB_OUTPUT
|
||||
echo "Valid version format found in PR title: $PR_TITLE"
|
||||
else
|
||||
echo "Error: PR title '$PR_TITLE' must start with 'v' (e.g., 'v1.0.0') to create a release."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Create Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
tag_name: ${{ steps.extract_version.outputs.version }}
|
||||
name: Release ${{ steps.extract_version.outputs.version }}
|
||||
body_path: pr_body.md
|
||||
draft: false
|
||||
prerelease: false
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: 3.12
|
||||
|
||||
- name: Upgrade pip
|
||||
run: python3 -m pip install --upgrade pip
|
||||
|
||||
- name: Install build
|
||||
run: python3 -m pip install --upgrade build twine setuptools
|
||||
|
||||
- name: Build a binary wheel and a source tarball
|
||||
run: python3 -m build --sdist --wheel --outdir dist/
|
||||
|
||||
- name: Publish distribution 📦 to PyPI
|
||||
uses: pypa/gh-action-pypi-publish@release/v1
|
||||
@@ -0,0 +1,124 @@
|
||||
name: Tests
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- dev
|
||||
paths-ignore:
|
||||
- '*.md'
|
||||
- '**/*.md'
|
||||
- 'docs/**'
|
||||
- 'images/**'
|
||||
- '.github/**'
|
||||
- 'agent-skill/**'
|
||||
- '*.yml'
|
||||
- '*.yaml'
|
||||
- 'ruff.toml'
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
- dev
|
||||
paths-ignore:
|
||||
- '*.md'
|
||||
- '**/*.md'
|
||||
- 'docs/**'
|
||||
- 'images/**'
|
||||
- '.github/**'
|
||||
- 'agent-skill/**'
|
||||
- '*.yml'
|
||||
- '*.yaml'
|
||||
- 'ruff.toml'
|
||||
|
||||
concurrency:
|
||||
group: ${{github.workflow}}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
tests:
|
||||
timeout-minutes: 60
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- python-version: "3.10"
|
||||
os: macos-latest
|
||||
env:
|
||||
TOXENV: py310
|
||||
- python-version: "3.11"
|
||||
os: macos-latest
|
||||
env:
|
||||
TOXENV: py311
|
||||
- python-version: "3.12"
|
||||
os: macos-latest
|
||||
env:
|
||||
TOXENV: py312
|
||||
- python-version: "3.13"
|
||||
os: macos-latest
|
||||
env:
|
||||
TOXENV: py313
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
cache: 'pip'
|
||||
cache-dependency-path: |
|
||||
pyproject.toml
|
||||
tox.ini
|
||||
|
||||
- name: Install all browsers dependencies
|
||||
run: |
|
||||
python3 -m pip install --upgrade pip
|
||||
python3 -m pip install playwright==1.61.0 patchright==1.61.1
|
||||
|
||||
- name: Get Playwright version
|
||||
id: playwright-version
|
||||
run: |
|
||||
PLAYWRIGHT_VERSION=$(python3 -c "import importlib.metadata; print(importlib.metadata.version('playwright'))")
|
||||
echo "version=$PLAYWRIGHT_VERSION" >> $GITHUB_OUTPUT
|
||||
echo "Playwright version: $PLAYWRIGHT_VERSION"
|
||||
|
||||
- name: Retrieve Playwright browsers from cache if any
|
||||
id: playwright-cache
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: |
|
||||
~/.cache/ms-playwright
|
||||
~/Library/Caches/ms-playwright
|
||||
~/.ms-playwright
|
||||
key: ${{ runner.os }}-playwright-${{ steps.playwright-version.outputs.version }}-v1
|
||||
restore-keys: |
|
||||
${{ runner.os }}-playwright-${{ steps.playwright-version.outputs.version }}-
|
||||
${{ runner.os }}-playwright-
|
||||
|
||||
- name: Install Playwright browsers
|
||||
run: |
|
||||
echo "Cache hit: ${{ steps.playwright-cache.outputs.cache-hit }}"
|
||||
if [ "${{ steps.playwright-cache.outputs.cache-hit }}" != "true" ]; then
|
||||
python3 -m playwright install chromium
|
||||
else
|
||||
echo "Skipping install - using cached Playwright browsers"
|
||||
fi
|
||||
python3 -m playwright install-deps chromium
|
||||
|
||||
# Cache tox environments
|
||||
- name: Cache tox environments
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: .tox
|
||||
# Include python version and os in the cache key
|
||||
key: tox-v1-${{ runner.os }}-py${{ matrix.python-version }}-${{ hashFiles('/Users/runner/work/Scrapling/pyproject.toml') }}
|
||||
restore-keys: |
|
||||
tox-v1-${{ runner.os }}-py${{ matrix.python-version }}-
|
||||
tox-v1-${{ runner.os }}-
|
||||
|
||||
- name: Install tox
|
||||
run: pip install -U tox
|
||||
|
||||
- name: Run tests
|
||||
env: ${{ matrix.env }}
|
||||
run: tox
|
||||
Reference in New Issue
Block a user