name: Run Pytest on: workflow_call: secrets: CODECOV_TOKEN: required: false permissions: contents: read concurrency: group: api-tests-${{ github.head_ref || github.run_id }} cancel-in-progress: true jobs: api-unit: name: API Unit Tests runs-on: depot-ubuntu-24.04 env: COVERAGE_FILE: coverage-unit defaults: run: shell: bash strategy: matrix: python-version: - "3.12" steps: - name: Checkout code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 persist-credentials: false - name: Setup UV and Python uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 with: enable-cache: true python-version: ${{ matrix.python-version }} cache-dependency-glob: api/uv.lock - name: Check UV lockfile run: uv lock --project api --check - name: Install dependencies run: uv sync --project api --dev - name: Run dify config tests run: uv run --project api pytest api/tests/unit_tests/configs/test_env_consistency.py - name: Run Unit Tests run: | uv run --project api pytest \ -p no:benchmark \ --timeout "${PYTEST_TIMEOUT:-20}" \ -n auto \ api/tests/unit_tests \ api/providers/vdb/*/tests/unit_tests \ api/providers/trace/*/tests/unit_tests \ --ignore=api/tests/unit_tests/controllers # Controller tests register Flask routes at import time, so keep them out of xdist. uv run --project api pytest \ --timeout "${PYTEST_TIMEOUT:-20}" \ --cov-append \ api/tests/unit_tests/controllers - name: Upload unit coverage data uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: api-coverage-unit path: coverage-unit retention-days: 1 api-integration: name: API Integration Tests runs-on: depot-ubuntu-24.04 env: COVERAGE_FILE: coverage-integration STORAGE_TYPE: opendal OPENDAL_SCHEME: fs OPENDAL_FS_ROOT: /tmp/dify-storage defaults: run: shell: bash strategy: matrix: python-version: - "3.12" steps: - name: Checkout code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 persist-credentials: false - name: Setup UV and Python uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 with: enable-cache: true python-version: ${{ matrix.python-version }} cache-dependency-glob: api/uv.lock - name: Check UV lockfile run: uv lock --project api --check - name: Install dependencies run: uv sync --project api --dev - name: Run Integration Tests run: | uv run --project api pytest \ -p no:benchmark \ --start-middleware \ -n auto \ --timeout "${PYTEST_TIMEOUT:-180}" \ api/tests/integration_tests/workflow \ api/tests/integration_tests/tools \ api/tests/test_containers_integration_tests - name: Upload integration coverage data uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: api-coverage-integration path: coverage-integration retention-days: 1 api-coverage: name: API Coverage runs-on: depot-ubuntu-24.04 needs: - api-unit - api-integration env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} COVERAGE_FILE: .coverage defaults: run: shell: bash steps: - name: Checkout code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 persist-credentials: false - name: Setup UV and Python uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 with: enable-cache: true python-version: "3.12" cache-dependency-glob: api/uv.lock - name: Install dependencies run: uv sync --project api --dev - name: Download coverage data uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: path: coverage-data pattern: api-coverage-* merge-multiple: true - name: Combine coverage run: | set -euo pipefail echo "### API Coverage" >> "$GITHUB_STEP_SUMMARY" echo "" >> "$GITHUB_STEP_SUMMARY" echo "Merged backend coverage report generated for Codecov project status." >> "$GITHUB_STEP_SUMMARY" echo "" >> "$GITHUB_STEP_SUMMARY" unit_coverage="$(find coverage-data -type f -name coverage-unit -print -quit)" integration_coverage="$(find coverage-data -type f -name coverage-integration -print -quit)" : "${unit_coverage:?coverage-unit artifact not found}" : "${integration_coverage:?coverage-integration artifact not found}" report_file="$(mktemp)" uv run --project api coverage combine "$unit_coverage" "$integration_coverage" uv run --project api coverage report --show-missing | tee "$report_file" echo "Summary: \`$(tail -n 1 "$report_file")\`" >> "$GITHUB_STEP_SUMMARY" { echo "" echo "
Coverage report" echo "" echo '```' cat "$report_file" echo '```' echo "
" } >> "$GITHUB_STEP_SUMMARY" uv run --project api coverage xml -o coverage.xml - name: Report coverage if: ${{ env.CODECOV_TOKEN != '' }} uses: codecov/codecov-action@e79a6962e0d4c0c17b229090214935d2e33f8354 # v6.0.1 with: files: ./coverage.xml disable_search: true flags: api env: CODECOV_TOKEN: ${{ env.CODECOV_TOKEN }}