diff --git a/.github/workflows/gh-page.yml b/.github/workflows/gh-page.yml index 9cec8767..1ab1e53a 100644 --- a/.github/workflows/gh-page.yml +++ b/.github/workflows/gh-page.yml @@ -7,10 +7,6 @@ on: - dev workflow_dispatch: inputs: - use_uv: - description: 'Use uv instead of Poetry' - required: false - default: 'false' dry_run: description: 'Dry-run build (no deploy)' required: false @@ -39,118 +35,38 @@ jobs: - uses: actions/setup-python@v5 with: python-version: "3.11" - # ===================== UV path (optional) ===================== + # ===================== UV only ===================== - name: Setup uv - if: ${{ github.event_name == 'workflow_dispatch' && inputs.use_uv == 'true' }} uses: astral-sh/setup-uv@v4 - name: Install dependencies (uv) - if: ${{ github.event_name == 'workflow_dispatch' && inputs.use_uv == 'true' }} run: | set -e - # First sync project dependencies to create the project env uv sync - # Then install theme into the project env (not --system) if [ -n "${{ secrets.GH_TOKEN }}" ]; then uv pip install git+https://${{ secrets.GH_TOKEN }}@github.com/squidfunk/mkdocs-material-insiders.git else echo "GH_TOKEN not set; installing mkdocs-material (public) instead" uv pip install mkdocs-material fi - # =================== Poetry path (default) ==================== - - name: Cache Poetry and dependencies - if: ${{ !(github.event_name == 'workflow_dispatch' && inputs.use_uv == 'true') }} - uses: actions/cache@v3 - with: - path: | - ~/.cache/pypoetry - .venv - key: ${{ runner.os }}-poetry-${{ hashFiles('**/poetry.lock') }} - restore-keys: | - ${{ runner.os }}-poetry- - - name: Preflight installer URL (retry) - if: ${{ !(github.event_name == 'workflow_dispatch' && inputs.use_uv == 'true') }} - uses: nick-fields/retry@v3 - with: - timeout_minutes: 2 - max_attempts: 3 - command: | - python - <<'PY' - import urllib.request - urllib.request.urlopen('https://install.python-poetry.org', timeout=10).read() - PY - - name: Install Poetry - id: install_poetry - if: ${{ !(github.event_name == 'workflow_dispatch' && inputs.use_uv == 'true') }} - uses: snok/install-poetry@v1 - with: - # 保持 latest,但显式指定 installer-url,减少 404 风险 - version: latest - virtualenvs-create: true - virtualenvs-in-project: true - installer-url: https://install.python-poetry.org - continue-on-error: true - - name: Fallback install Poetry via pipx (if action failed) - if: ${{ !(github.event_name == 'workflow_dispatch' && inputs.use_uv == 'true') && steps.install_poetry.outcome == 'failure' }} - run: | - python -m pip install --user pipx - python -m pipx ensurepath - ~/.local/bin/pipx install poetry - echo "$HOME/.local/bin" >> $GITHUB_PATH - - name: Install dependencies (Poetry) - if: ${{ !(github.event_name == 'workflow_dispatch' && inputs.use_uv == 'true') }} - run: | - poetry run pip install --upgrade pip - set -e - if [ -n "${{ secrets.GH_TOKEN }}" ]; then - poetry run pip install git+https://${{ secrets.GH_TOKEN }}@github.com/squidfunk/mkdocs-material-insiders.git - else - echo "GH_TOKEN not set; installing mkdocs-material (public) instead" - poetry run pip install mkdocs-material - fi - poetry install - # ======================== Convert Notebooks ======================== - - name: Convert notebooks to markdown - if: ${{ github.event_name != 'workflow_dispatch' || inputs.dry_run != 'true' }} - run: | - chmod +x scripts/convert_notebooks.sh - if [ "${{ github.event_name == 'workflow_dispatch' && inputs.use_uv }}" = "true" ]; then - ./scripts/convert_notebooks.sh - else - poetry run jupyter nbconvert --to markdown $(find docs/tutorial -name "*.ipynb" -type f ! -path "*/.ipynb_checkpoints/*") --output-dir docs/tutorial - fi + # mkdocs-jupyter handles notebooks at build time; no manual conversion needed # ======================== Dry-run build ======================== - name: Build docs only (dry-run) if: ${{ github.event_name == 'workflow_dispatch' && inputs.dry_run == 'true' }} run: | - chmod +x scripts/convert_notebooks.sh - ./scripts/convert_notebooks.sh - if [ "${{ github.event_name == 'workflow_dispatch' && inputs.use_uv }}" = "true" ]; then - uv run mkdocs build --strict - else - poetry run mkdocs build --strict - fi + uv run mkdocs build --strict # ========================= Deploy steps ======================== - name: Deploy documentation (dev branch) if: ${{ (github.event_name != 'workflow_dispatch' || inputs.dry_run != 'true') && github.ref == 'refs/heads/dev' }} run: | git fetch origin gh-pages --depth=1 || true - if [ "${{ github.event_name == 'workflow_dispatch' && inputs.use_uv }}" = "true" ]; then - uv run mike deploy --push dev - else - poetry run mike deploy --push dev - fi + uv run mike deploy --push dev - name: Deploy documentation (master branch) if: ${{ (github.event_name != 'workflow_dispatch' || inputs.dry_run != 'true') && github.ref == 'refs/heads/master' }} run: | git fetch origin gh-pages --depth=1 || true - if [ "${{ github.event_name == 'workflow_dispatch' && inputs.use_uv }}" = "true" ]; then - uv run mike deploy --push --update-aliases 0.8 latest - uv run mike set-default --push latest - else - poetry run mike deploy --push --update-aliases 0.8 latest - poetry run mike set-default --push latest - fi + uv run mike deploy --push --update-aliases 0.8 latest + uv run mike set-default --push latest - name: Deploy documentation (version tags) if: ${{ (github.event_name != 'workflow_dispatch' || inputs.dry_run != 'true') && startsWith(github.ref, 'refs/tags/v') }} @@ -158,12 +74,7 @@ jobs: git fetch origin gh-pages --depth=1 || true VERSION=${GITHUB_REF#refs/tags/v} MAJOR_MINOR=$(echo $VERSION | cut -d. -f1-2) - if [ "${{ github.event_name == 'workflow_dispatch' && inputs.use_uv }}" = "true" ]; then - uv run mike deploy --push --update-aliases $MAJOR_MINOR latest - uv run mike set-default --push latest - else - poetry run mike deploy --push --update-aliases $MAJOR_MINOR latest - poetry run mike set-default --push latest - fi + uv run mike deploy --push --update-aliases $MAJOR_MINOR latest + uv run mike set-default --push latest env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/test-notebooks.yml b/.github/workflows/test-notebooks.yml index 353566f7..8dd7360e 100644 --- a/.github/workflows/test-notebooks.yml +++ b/.github/workflows/test-notebooks.yml @@ -18,8 +18,7 @@ jobs: python-version: '3.11' - name: Install uv - run: | - pip install uv + uses: astral-sh/setup-uv@v4 - name: Install deps run: | @@ -29,5 +28,11 @@ jobs: env: ABSESPY_PROJECT_ROOT: ${{ github.workspace }} run: | - pytest - + set -e + NB_LIST=$(git ls-files 'docs/**/*.ipynb' | grep -v '^site/' || true) + if [ -z "$NB_LIST" ]; then + echo "No notebooks found under docs/. Skipping nbmake." + exit 0 + fi + echo "Notebooks to test:" && echo "$NB_LIST" + uv run pytest --nbmake $NB_LIST -v --tb=short --ignore=site diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index bfcd556d..1f192918 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -10,8 +10,8 @@ concurrency: cancel-in-progress: true jobs: - foundation-tests: - name: Foundation Tests + lint: + name: Lint and Type Check runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -24,70 +24,20 @@ jobs: - name: Install uv uses: astral-sh/setup-uv@v4 - - name: Cache uv - uses: actions/cache@v4 - with: - path: ~/.cache/uv - key: ${{ runner.os }}-py3.11-uv-${{ hashFiles('**/pyproject.toml', '**/uv.lock') }} - restore-keys: | - ${{ runner.os }}-py3.11-uv- - - name: Install dependencies run: | uv sync --dev - - name: Run foundation tests - run: | - uv run pytest tests/foundation/ -v --tb=short --cov=abses --cov-report=xml - - - name: Upload foundation test coverage - uses: codecov/codecov-action@v4 - with: - fail_ci_if_error: false - file: ./coverage.xml - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - - scenario-tests: - name: Scenario Tests - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install uv - uses: astral-sh/setup-uv@v4 - - - name: Cache uv - uses: actions/cache@v4 - with: - path: ~/.cache/uv - key: ${{ runner.os }}-py3.11-uv-${{ hashFiles('**/pyproject.toml', '**/uv.lock') }} - restore-keys: | - ${{ runner.os }}-py3.11-uv- - - - name: Install dependencies + - name: Run ruff run: | - uv sync --dev + uv run ruff check abses/ --output-format=github - - name: Run scenario tests + - name: Run mypy run: | - uv run pytest tests/scenarios/ -v --tb=short --cov=abses --cov-report=xml - - - name: Upload scenario test coverage - uses: codecov/codecov-action@v4 - with: - fail_ci_if_error: false - file: ./coverage.xml - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + uv run mypy abses/ - test: - name: Test Python ${{ matrix.python-version }} on ${{ matrix.os }} + tests: + name: Tests ${{ matrix.python-version }} on ${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: fail-fast: false @@ -118,177 +68,16 @@ jobs: run: | uv sync --dev - - name: Run tests + - name: Run Make test-all (unit + notebooks + tox) run: | - uv run pytest tests/ -v --tb=short + uv run make test-all - - name: Upload coverage reports + - name: Upload coverage (3.11 on ubuntu) if: matrix.python-version == '3.11' && matrix.os == 'ubuntu-latest' uses: codecov/codecov-action@v4 with: fail_ci_if_error: false + file: ./coverage.xml env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - performance-tests: - name: Performance Benchmark Tests - runs-on: ubuntu-latest - if: github.event_name == 'pull_request' - steps: - - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install uv - uses: astral-sh/setup-uv@v4 - - - name: Cache uv - uses: actions/cache@v4 - with: - path: ~/.cache/uv - key: ${{ runner.os }}-py3.11-uv-${{ hashFiles('**/pyproject.toml', '**/uv.lock') }} - restore-keys: | - ${{ runner.os }}-py3.11-uv- - - - name: Install dependencies - run: | - uv sync --dev - - - name: Install pytest-benchmark - run: | - uv add pytest-benchmark - - - name: Run performance benchmarks - run: | - uv run pytest tests/performance/ -v --benchmark-only --benchmark-save=baseline - - - name: Compare with baseline - run: | - uv run pytest tests/performance/ -v --benchmark-compare=baseline --benchmark-compare-fail=mean:20% - - - name: Upload benchmark results - uses: actions/upload-artifact@v4 - with: - name: benchmark-results - path: .benchmarks/ - - lint: - name: Lint and Type Check - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install uv - uses: astral-sh/setup-uv@v4 - - - name: Install dependencies - run: | - uv sync --dev - - - name: Run ruff - run: | - uv run ruff check abses/ --output-format=github - - - name: Run mypy - run: | - uv run mypy abses/ - - integration-tests: - name: Integration Tests - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install uv - uses: astral-sh/setup-uv@v4 - - - name: Cache uv - uses: actions/cache@v4 - with: - path: ~/.cache/uv - key: ${{ runner.os }}-py3.11-uv-${{ hashFiles('**/pyproject.toml', '**/uv.lock') }} - restore-keys: | - ${{ runner.os }}-py3.11-uv- - - - name: Install dependencies - run: | - uv sync --dev - - - name: Run integration tests - run: | - uv run pytest tests/integration/ -v --tb=short - - regression-tests: - name: Regression Tests - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install uv - uses: astral-sh/setup-uv@v4 - - - name: Cache uv - uses: actions/cache@v4 - with: - path: ~/.cache/uv - key: ${{ runner.os }}-py3.11-uv-${{ hashFiles('**/pyproject.toml', '**/uv.lock') }} - restore-keys: | - ${{ runner.os }}-py3.11-uv- - - - name: Install dependencies - run: | - uv sync --dev - - - name: Run regression tests - run: | - uv run pytest tests/regression/ -v --tb=short - - - name: Run backward compatibility tests - run: | - uv run pytest tests/test_backward_compatibility.py -v --tb=short - - test-matrix-summary: - name: Test Matrix Summary - runs-on: ubuntu-latest - needs: [foundation-tests, test, lint, scenario-tests] - if: always() - steps: - - name: Check test results - run: | - if [ "${{ needs.foundation-tests.result }}" != "success" ]; then - echo "❌ Foundation tests failed" - exit 1 - fi - if [ "${{ needs.test.result }}" != "success" ]; then - echo "❌ Tests failed on one or more Python versions" - exit 1 - fi - if [ "${{ needs.lint.result }}" != "success" ]; then - echo "⚠️ Linting or type checking issues detected (continuing)" - fi - if [ "${{ needs.scenario-tests.result }}" != "success" ]; then - echo "❌ Scenario tests failed" - exit 1 - fi - echo "✅ All tests passed across Python 3.11, 3.12, and 3.13!" - echo "✅ Foundation tests passed!" - echo "✅ Scenario tests passed!" -