Fix extraction grounding bugs: page fallback, idempotency, label-set scoping #4434
Workflow file for this run
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: Backend CI | |
| # Enable Buildkit and let compose use it to speed up image building | |
| env: | |
| DOCKER_BUILDKIT: 1 | |
| COMPOSE_DOCKER_CLI_BUILD: 1 | |
| SKLEARN_ALLOW_DEPRECATED_SKLEARN_PACKAGE_INSTALL: True | |
| defaults: | |
| run: | |
| working-directory: ./ | |
| on: | |
| pull_request: | |
| branches: [ "master", "main", "v*" ] | |
| paths-ignore: [ "docs/**" ] | |
| push: | |
| branches: [ "master", "main", "v*" ] | |
| paths-ignore: [ "docs/**" ] | |
| concurrency: | |
| group: ${{ github.head_ref || github.run_id }} | |
| cancel-in-progress: true | |
| jobs: | |
| changes: | |
| # Path filtering only gates pull_request events; pushes to protected | |
| # branches always run downstream regardless of which files changed. | |
| # dorny/paths-filter@v4 additionally needs a checked-out repo on push | |
| # events (it shells out to `git branch --show-current`), so scoping | |
| # this job to pull_request avoids the "fatal: not a git repository" | |
| # red X that would otherwise appear on every push to main. | |
| if: github.event_name == 'pull_request' | |
| runs-on: ubuntu-latest | |
| # Fail open: if this job errors (e.g., transient GitHub API failure), | |
| # downstream jobs should still run rather than being silently skipped. | |
| continue-on-error: true | |
| permissions: | |
| contents: read | |
| pull-requests: read | |
| outputs: | |
| backend: ${{ steps.filter.outputs.backend }} | |
| steps: | |
| # No checkout needed: dorny/paths-filter@v4 reads diffs from the | |
| # pull_request event payload. | |
| - uses: dorny/paths-filter@v4 | |
| id: filter | |
| with: | |
| filters: | | |
| backend: | |
| - 'opencontractserver/**' | |
| - 'config/**' | |
| - '*.py' | |
| - 'requirements/**' | |
| - 'test.yml' | |
| - 'compose/**' | |
| - 'Dockerfile*' | |
| - '.pre-commit-config.yaml' | |
| - 'setup.cfg' | |
| - 'mypy.ini' | |
| - 'pyproject.toml' | |
| - '.github/workflows/backend.yml' | |
| linter: | |
| needs: changes | |
| # Run on every push, and on PRs unless the filter explicitly reports | |
| # no backend changes ('false'). `always()` is required because the | |
| # `changes` job is skipped on push events (see its `if:` above), and | |
| # a skipped `needs` target would otherwise cascade-skip this job. | |
| # The `!= 'false'` form also preserves the fail-open behaviour on | |
| # PRs where `changes` errors transiently (outputs.backend is ''). | |
| if: always() && (github.event_name == 'push' || needs.changes.outputs.backend != 'false') | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - name: Checkout Code Repository | |
| uses: actions/checkout@v6 | |
| - name: Set up Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.12" | |
| cache: pip | |
| cache-dependency-path: | | |
| requirements/base.txt | |
| requirements/local.txt | |
| - name: Install dependencies | |
| run: pip install -r requirements/local.txt | |
| - name: Run pre-commit | |
| run: pre-commit run --all-files | |
| - name: Run mypy | |
| # Runs from requirements/local.txt (not via pre-commit) so CI is | |
| # authoritative even when contributors skip the hook. Keep the | |
| # mypy pin in requirements/local.txt in sync with the `rev:` of | |
| # the mirrors-mypy hook in .pre-commit-config.yaml — a drift | |
| # means the hook and CI can disagree silently. See | |
| # docs/typing/README.md. | |
| run: python -m mypy --config-file mypy.ini opencontractserver config | |
| pytest: | |
| needs: [changes, linter] | |
| # Same fail-open semantics as the linter gate above. | |
| if: always() && needs.linter.result == 'success' && (github.event_name == 'push' || needs.changes.outputs.backend != 'false') | |
| runs-on: yuge | |
| timeout-minutes: 180 | |
| permissions: | |
| contents: read | |
| actions: read | |
| steps: | |
| - name: Checkout Code Repository | |
| uses: actions/checkout@v6 | |
| - name: Store Codecov Env Flags | |
| continue-on-error: true | |
| run: | | |
| ci_env=`bash <(curl -s https://codecov.io/env)` | |
| echo "$ci_env" | |
| - name: Build the Stack | |
| run: docker compose -f test.yml build | |
| - name: Run DB Migrations | |
| run: docker compose -f test.yml run --rm django python manage.py migrate | |
| - name: Collect Static Files | |
| run: docker compose -f test.yml run --rm django python manage.py collectstatic | |
| - name: Verify Docker Containers | |
| run: | | |
| docker compose -f test.yml ps | |
| - name: Capture Docker Compose Logs | |
| if: failure() | |
| run: | | |
| docker compose -f test.yml logs --no-color > docker-compose-logs.txt | |
| - name: Upload Docker Compose Logs | |
| if: failure() | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: docker-compose-logs | |
| path: docker-compose-logs.txt | |
| - name: Check Container Health | |
| run: | | |
| echo "=== Docker containers status ===" | |
| docker compose -f test.yml ps | |
| echo "=== Container logs (last 20 lines each) ===" | |
| for container in $(docker compose -f test.yml ps -q); do | |
| name=$(docker inspect -f '{{.Name}}' $container | sed 's/^\///') | |
| echo "--- Logs for $name ---" | |
| docker logs --tail 20 $container 2>&1 || true | |
| done | |
| echo "=== Memory usage ===" | |
| docker stats --no-stream | |
| free -h | |
| - name: Build Pytest Coverage File | |
| timeout-minutes: 100 | |
| run: | | |
| # Run the full test suite with coverage using parallel workers | |
| # pytest-cov with pytest-xdist handles coverage merging automatically | |
| docker compose -f test.yml run django pytest --cov --cov-report=xml -n auto --dist loadscope -v | |
| - name: Verify Coverage File Exists | |
| run: | | |
| # Verify coverage.xml exists in the working directory | |
| ls -la coverage.xml | |
| - name: Upload Coverage Reports to Codecov | |
| uses: codecov/codecov-action@v6 | |
| with: | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| files: ./coverage.xml | |
| flags: backend | |
| name: backend-coverage | |
| fail_ci_if_error: false | |
| - name: Tear down the Stack | |
| run: docker compose -f test.yml down |