diff --git a/.github/dependabot.yml b/.github/dependabot.yml index cd382d5394..0075506c4c 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -7,4 +7,4 @@ updates: schedule: interval: 'daily' cooldown: - default-days: 1 + default-days: 7 diff --git a/.github/workflows/CI_pypi_release.yml b/.github/workflows/CI_pypi_release.yml index 2db9cee438..996169f576 100644 --- a/.github/workflows/CI_pypi_release.yml +++ b/.github/workflows/CI_pypi_release.yml @@ -43,14 +43,18 @@ jobs: pip install hatch requests --uploaded-prior-to=P1D - name: Validate version number - run: python .github/utils/validate_version.py --tag ${{ github.ref_name }} + env: + REF_NAME: ${{ github.ref_name }} + run: python .github/utils/validate_version.py --tag "$REF_NAME" - name: Get project folder id: pathfinder shell: python + env: + REF_NAME: ${{ github.ref_name }} run: | import os - project_path = "${{ github.ref_name }}".rsplit("-", maxsplit=1)[0] + project_path = os.environ["REF_NAME"].rsplit("-", maxsplit=1)[0] with open(os.environ['GITHUB_OUTPUT'], 'a') as f: print(f'project_path={project_path}', file=f) diff --git a/.github/workflows/aimlapi.yml b/.github/workflows/aimlapi.yml index f5dfd8f8a8..6b5838abca 100644 --- a/.github/workflows/aimlapi.yml +++ b/.github/workflows/aimlapi.yml @@ -29,7 +29,6 @@ concurrency: env: PYTHONUNBUFFERED: "1" FORCE_COLOR: "1" - AIMLAPI_API_KEY: ${{ secrets.AIMLAPI_API_KEY }} TEST_MATRIX_OS: '["ubuntu-latest", "windows-latest", "macos-latest"]' TEST_MATRIX_PYTHON: '["3.10", "3.14"]' @@ -106,6 +105,8 @@ jobs: path: python-coverage-comment-action-aimlapi.txt - name: Run integration tests + env: + AIMLAPI_API_KEY: ${{ secrets.AIMLAPI_API_KEY }} run: hatch run test:integration-cov-append-retry - name: Store combined coverage @@ -128,6 +129,8 @@ jobs: # Since this integration inherits from OpenAIChatGenerator, we run ALL tests with Haystack main branch to catch regressions - name: Nightly - run tests with Haystack main branch if: github.event_name == 'schedule' + env: + AIMLAPI_API_KEY: ${{ secrets.AIMLAPI_API_KEY }} run: | hatch env prune hatch -e test env run -- uv pip install git+https://github.com/deepset-ai/haystack.git@main diff --git a/.github/workflows/amazon_bedrock.yml b/.github/workflows/amazon_bedrock.yml index a5a2f6a78f..0883b2f8ab 100644 --- a/.github/workflows/amazon_bedrock.yml +++ b/.github/workflows/amazon_bedrock.yml @@ -37,9 +37,7 @@ env: TEST_MATRIX_PYTHON: '["3.10", "3.14"]' AWS_REGION: "us-east-1" - AWS_BEDROCK_GUARDRAIL_ID: ${{ secrets.AWS_BEDROCK_GUARDRAIL_ID }} AWS_BEDROCK_GUARDRAIL_VERSION: "1" - S3_DOWNLOADER_BUCKET: ${{ secrets.S3_DOWNLOADER_BUCKET }} jobs: compute-test-matrix: @@ -125,6 +123,9 @@ jobs: - name: Run integration tests if: success() && steps.aws-auth.outcome == 'success' + env: + AWS_BEDROCK_GUARDRAIL_ID: ${{ secrets.AWS_BEDROCK_GUARDRAIL_ID }} + S3_DOWNLOADER_BUCKET: ${{ secrets.S3_DOWNLOADER_BUCKET }} run: hatch run test:integration-cov-append-retry - name: Store combined coverage diff --git a/.github/workflows/anthropic.yml b/.github/workflows/anthropic.yml index b4d528bd12..0229f8f092 100644 --- a/.github/workflows/anthropic.yml +++ b/.github/workflows/anthropic.yml @@ -29,7 +29,6 @@ concurrency: env: PYTHONUNBUFFERED: "1" FORCE_COLOR: "1" - ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} TEST_MATRIX_OS: '["ubuntu-latest", "windows-latest", "macos-latest"]' TEST_MATRIX_PYTHON: '["3.10", "3.14"]' @@ -106,6 +105,8 @@ jobs: path: python-coverage-comment-action-anthropic.txt - name: Run integration tests + env: + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} run: hatch run test:integration-cov-append-retry - name: Store combined coverage diff --git a/.github/workflows/arcadedb.yml b/.github/workflows/arcadedb.yml index b5d2960806..acbacf2aeb 100644 --- a/.github/workflows/arcadedb.yml +++ b/.github/workflows/arcadedb.yml @@ -26,8 +26,6 @@ env: PYTHONUNBUFFERED: "1" FORCE_COLOR: "1" ARCADEDB_USERNAME: "root" - # Only set in main repo (secrets not passed to fork workflows); integration tests skip when unset - ARCADEDB_PASSWORD: ${{ secrets.ARCADEDB_PASSWORD }} TEST_MATRIX_OS: '["ubuntu-latest"]' TEST_MATRIX_PYTHON: '["3.10", "3.14"]' @@ -111,6 +109,9 @@ jobs: path: python-coverage-comment-action-arcadedb.txt - name: Run integration tests + env: + # Only set in main repo (secrets not passed to fork workflows); integration tests skip when unset + ARCADEDB_PASSWORD: ${{ secrets.ARCADEDB_PASSWORD }} run: hatch run test:integration-cov-append-retry - name: Store combined coverage diff --git a/.github/workflows/azure_ai_search.yml b/.github/workflows/azure_ai_search.yml index 645743b08e..72ebd66743 100644 --- a/.github/workflows/azure_ai_search.yml +++ b/.github/workflows/azure_ai_search.yml @@ -25,8 +25,6 @@ concurrency: env: PYTHONUNBUFFERED: "1" FORCE_COLOR: "1" - AZURE_AI_SEARCH_API_KEY: ${{ secrets.AZURE_AI_SEARCH_API_KEY }} - AZURE_AI_SEARCH_ENDPOINT: ${{ secrets.AZURE_AI_SEARCH_ENDPOINT }} TEST_MATRIX_OS: '["ubuntu-latest", "windows-latest"]' TEST_MATRIX_PYTHON: '["3.10", "3.14"]' @@ -103,6 +101,9 @@ jobs: path: python-coverage-comment-action-azure_ai_search.txt - name: Run integration tests + env: + AZURE_AI_SEARCH_API_KEY: ${{ secrets.AZURE_AI_SEARCH_API_KEY }} + AZURE_AI_SEARCH_ENDPOINT: ${{ secrets.AZURE_AI_SEARCH_ENDPOINT }} run: hatch run test:integration-cov-append-retry - name: Store combined coverage diff --git a/.github/workflows/azure_doc_intelligence.yml b/.github/workflows/azure_doc_intelligence.yml index 6e480d908e..ed0fcbfdd8 100644 --- a/.github/workflows/azure_doc_intelligence.yml +++ b/.github/workflows/azure_doc_intelligence.yml @@ -25,8 +25,6 @@ concurrency: env: PYTHONUNBUFFERED: "1" FORCE_COLOR: "1" - AZURE_DI_ENDPOINT: ${{ secrets.AZURE_DI_ENDPOINT }} - AZURE_AI_API_KEY: ${{ secrets.AZURE_AI_API_KEY }} TEST_MATRIX_OS: '["ubuntu-latest", "windows-latest"]' TEST_MATRIX_PYTHON: '["3.10", "3.14"]' @@ -103,6 +101,9 @@ jobs: path: python-coverage-comment-action-azure_doc_intelligence.txt - name: Run integration tests + env: + AZURE_DI_ENDPOINT: ${{ secrets.AZURE_DI_ENDPOINT }} + AZURE_AI_API_KEY: ${{ secrets.AZURE_AI_API_KEY }} run: hatch run test:integration-cov-append-retry - name: Store combined coverage diff --git a/.github/workflows/azure_form_recognizer.yml b/.github/workflows/azure_form_recognizer.yml index 081731b1da..3e092ba7dc 100644 --- a/.github/workflows/azure_form_recognizer.yml +++ b/.github/workflows/azure_form_recognizer.yml @@ -25,8 +25,6 @@ concurrency: env: PYTHONUNBUFFERED: "1" FORCE_COLOR: "1" - CORE_AZURE_CS_ENDPOINT: ${{ secrets.CORE_AZURE_CS_ENDPOINT }} - CORE_AZURE_CS_API_KEY: ${{ secrets.CORE_AZURE_CS_API_KEY }} TEST_MATRIX_OS: '["ubuntu-latest", "windows-latest", "macos-latest"]' TEST_MATRIX_PYTHON: '["3.10", "3.14"]' @@ -103,6 +101,9 @@ jobs: path: python-coverage-comment-action-azure_form_recognizer.txt - name: Run integration tests + env: + CORE_AZURE_CS_ENDPOINT: ${{ secrets.CORE_AZURE_CS_ENDPOINT }} + CORE_AZURE_CS_API_KEY: ${{ secrets.CORE_AZURE_CS_API_KEY }} run: hatch run test:integration-cov-append-retry - name: Store combined coverage diff --git a/.github/workflows/brave.yml b/.github/workflows/brave.yml index 22870b6113..69ad2b5f59 100644 --- a/.github/workflows/brave.yml +++ b/.github/workflows/brave.yml @@ -29,7 +29,6 @@ concurrency: env: PYTHONUNBUFFERED: "1" FORCE_COLOR: "1" - BRAVE_API_KEY: ${{ secrets.BRAVE_API_KEY }} TEST_MATRIX_OS: '["ubuntu-latest", "windows-latest", "macos-latest"]' TEST_MATRIX_PYTHON: '["3.10", "3.14"]' @@ -104,6 +103,8 @@ jobs: path: python-coverage-comment-action-brave.txt - name: Run integration tests + env: + BRAVE_API_KEY: ${{ secrets.BRAVE_API_KEY }} run: hatch run test:integration-cov-append-retry - name: Store combined coverage @@ -125,6 +126,8 @@ jobs: - name: Nightly - run tests with Haystack main branch if: github.event_name == 'schedule' + env: + BRAVE_API_KEY: ${{ secrets.BRAVE_API_KEY }} run: | hatch env prune hatch -e test env run -- uv pip install git+https://github.com/deepset-ai/haystack.git@main diff --git a/.github/workflows/chonkie.yml b/.github/workflows/chonkie.yml index b4043ab8f0..4b60860259 100644 --- a/.github/workflows/chonkie.yml +++ b/.github/workflows/chonkie.yml @@ -29,7 +29,6 @@ concurrency: env: PYTHONUNBUFFERED: "1" FORCE_COLOR: "1" - HF_TOKEN: ${{ secrets.HF_TOKEN }} TEST_MATRIX_OS: '["ubuntu-latest", "windows-latest", "macos-latest"]' TEST_MATRIX_PYTHON: '["3.10", "3.13"]' @@ -106,6 +105,8 @@ jobs: - name: Run integration tests run: hatch run test:integration-cov-append-retry + env: + HF_TOKEN: ${{ secrets.HF_TOKEN }} - name: Store combined coverage if: github.event_name == 'push' diff --git a/.github/workflows/cognee.yml b/.github/workflows/cognee.yml index fd358c2252..93b64b9761 100644 --- a/.github/workflows/cognee.yml +++ b/.github/workflows/cognee.yml @@ -29,8 +29,6 @@ concurrency: env: PYTHONUNBUFFERED: "1" FORCE_COLOR: "1" - # cognee runs an LLM internally for remember/recall/improve; the integration suite needs a key. - LLM_API_KEY: ${{ secrets.OPENAI_API_KEY }} TEST_MATRIX_OS: '["ubuntu-latest", "windows-latest", "macos-latest"]' TEST_MATRIX_PYTHON: '["3.10", "3.14"]' @@ -108,6 +106,9 @@ jobs: - name: Run integration tests run: hatch run test:integration-cov-append-retry + env: + # cognee runs an LLM internally for remember/recall/improve; the integration suite needs a key. + LLM_API_KEY: ${{ secrets.OPENAI_API_KEY }} - name: Store combined coverage if: github.event_name == 'push' diff --git a/.github/workflows/cohere.yml b/.github/workflows/cohere.yml index ce245fc9f8..fafe1eeb84 100644 --- a/.github/workflows/cohere.yml +++ b/.github/workflows/cohere.yml @@ -29,7 +29,6 @@ concurrency: env: PYTHONUNBUFFERED: "1" FORCE_COLOR: "1" - COHERE_API_KEY: ${{ secrets.COHERE_API_KEY }} TEST_MATRIX_OS: '["ubuntu-latest", "windows-latest", "macos-latest"]' TEST_MATRIX_PYTHON: '["3.10", "3.14"]' @@ -107,6 +106,8 @@ jobs: - name: Run integration tests run: hatch run test:integration-cov-append-retry + env: + COHERE_API_KEY: ${{ secrets.COHERE_API_KEY }} - name: Store combined coverage if: github.event_name == 'push' diff --git a/.github/workflows/cometapi.yml b/.github/workflows/cometapi.yml index a6cb0a95b7..dc6aa121ec 100644 --- a/.github/workflows/cometapi.yml +++ b/.github/workflows/cometapi.yml @@ -29,7 +29,6 @@ concurrency: env: PYTHONUNBUFFERED: "1" FORCE_COLOR: "1" - COMET_API_KEY: "${{ secrets.COMET_API_KEY }}" TEST_MATRIX_OS: '["ubuntu-latest", "windows-latest", "macos-latest"]' TEST_MATRIX_PYTHON: '["3.10", "3.14"]' @@ -107,6 +106,8 @@ jobs: - name: Run integration tests run: hatch run test:integration-cov-append-retry + env: + COMET_API_KEY: "${{ secrets.COMET_API_KEY }}" - name: Store combined coverage if: github.event_name == 'push' @@ -128,6 +129,8 @@ jobs: # Since this integration inherits from OpenAIChatGenerator, we run ALL tests with Haystack main branch to catch regressions - name: Nightly - run tests with Haystack main branch if: github.event_name == 'schedule' + env: + COMET_API_KEY: "${{ secrets.COMET_API_KEY }}" run: | hatch env prune hatch -e test env run -- uv pip install git+https://github.com/deepset-ai/haystack.git@main diff --git a/.github/workflows/deepeval.yml b/.github/workflows/deepeval.yml index 2f3403769d..839533509f 100644 --- a/.github/workflows/deepeval.yml +++ b/.github/workflows/deepeval.yml @@ -29,7 +29,6 @@ concurrency: env: PYTHONUNBUFFERED: "1" FORCE_COLOR: "1" - OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} TEST_MATRIX_OS: '["ubuntu-latest", "windows-latest", "macos-latest"]' TEST_MATRIX_PYTHON: '["3.10", "3.14"]' @@ -106,6 +105,8 @@ jobs: - name: Run integration tests run: hatch run test:integration-cov-append-retry + env: + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} - name: Store combined coverage if: github.event_name == 'push' diff --git a/.github/workflows/dspy.yml b/.github/workflows/dspy.yml index 5689afb392..9a6a841c4e 100644 --- a/.github/workflows/dspy.yml +++ b/.github/workflows/dspy.yml @@ -29,7 +29,6 @@ concurrency: env: PYTHONUNBUFFERED: "1" FORCE_COLOR: "1" - OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} TEST_MATRIX_OS: '["ubuntu-latest", "windows-latest", "macos-latest"]' TEST_MATRIX_PYTHON: '["3.10", "3.14"]' @@ -107,6 +106,8 @@ jobs: - name: Run integration tests run: hatch run test:integration-cov-append-retry + env: + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} - name: Store combined coverage if: github.event_name == 'push' diff --git a/.github/workflows/e2b.yml b/.github/workflows/e2b.yml index ad86207228..25dafb7089 100644 --- a/.github/workflows/e2b.yml +++ b/.github/workflows/e2b.yml @@ -29,7 +29,6 @@ concurrency: env: PYTHONUNBUFFERED: "1" FORCE_COLOR: "1" - E2B_API_KEY: ${{ secrets.E2B_API_KEY }} TEST_MATRIX_OS: '["ubuntu-latest", "windows-latest", "macos-latest"]' TEST_MATRIX_PYTHON: '["3.10", "3.14"]' @@ -61,6 +60,12 @@ jobs: os: ${{ fromJSON(needs.compute-test-matrix.outputs.os) }} python-version: ${{ fromJSON(needs.compute-test-matrix.outputs.python-version) }} + # Scoped to this job (not the workflow-level env) so the secret is not exposed to other + # jobs, while remaining available to the "Run integration tests" step's `if:` condition + # (a step's own step-level env is not in scope for that same step's `if`). + env: + E2B_API_KEY: ${{ secrets.E2B_API_KEY }} + steps: - name: Support longpaths if: matrix.os == 'windows-latest' diff --git a/.github/workflows/fastembed.yml b/.github/workflows/fastembed.yml index 0cbbe51c10..d77b00ada8 100644 --- a/.github/workflows/fastembed.yml +++ b/.github/workflows/fastembed.yml @@ -23,7 +23,6 @@ defaults: env: PYTHONUNBUFFERED: "1" FORCE_COLOR: "1" - HF_TOKEN: ${{ secrets.HF_TOKEN }} TEST_MATRIX_OS: '["ubuntu-latest", "windows-latest", "macos-latest"]' TEST_MATRIX_PYTHON: '["3.10", "3.13"]' @@ -95,6 +94,8 @@ jobs: - name: Run integration tests run: hatch run test:integration-cov-append-retry + env: + HF_TOKEN: ${{ secrets.HF_TOKEN }} - name: Store combined coverage if: github.event_name == 'push' diff --git a/.github/workflows/firecrawl.yml b/.github/workflows/firecrawl.yml index 9c5e3cd300..d7ad12850d 100644 --- a/.github/workflows/firecrawl.yml +++ b/.github/workflows/firecrawl.yml @@ -25,7 +25,6 @@ concurrency: env: PYTHONUNBUFFERED: "1" FORCE_COLOR: "1" - FIRECRAWL_API_KEY: ${{ secrets.FIRECRAWL_API_KEY }} TEST_MATRIX_OS: '["ubuntu-latest", "windows-latest", "macos-latest"]' TEST_MATRIX_PYTHON: '["3.10", "3.14"]' @@ -101,6 +100,8 @@ jobs: path: python-coverage-comment-action-firecrawl.txt - name: Run integration tests + env: + FIRECRAWL_API_KEY: ${{ secrets.FIRECRAWL_API_KEY }} run: hatch run test:integration-cov-append-retry - name: Store combined coverage diff --git a/.github/workflows/google_genai.yml b/.github/workflows/google_genai.yml index 7f104b3c50..05a9822462 100644 --- a/.github/workflows/google_genai.yml +++ b/.github/workflows/google_genai.yml @@ -29,7 +29,6 @@ concurrency: env: PYTHONUNBUFFERED: "1" FORCE_COLOR: "1" - GOOGLE_API_KEY: "${{ secrets.GOOGLE_API_KEY }}" TEST_MATRIX_OS: '["ubuntu-latest", "windows-latest", "macos-latest"]' TEST_MATRIX_PYTHON: '["3.10", "3.14"]' @@ -106,6 +105,8 @@ jobs: path: python-coverage-comment-action-google_genai.txt - name: Run integration tests + env: + GOOGLE_API_KEY: "${{ secrets.GOOGLE_API_KEY }}" run: hatch run test:integration-cov-append-retry - name: Store combined coverage diff --git a/.github/workflows/huggingface_api.yml b/.github/workflows/huggingface_api.yml index 9b23d885c0..de5304c715 100644 --- a/.github/workflows/huggingface_api.yml +++ b/.github/workflows/huggingface_api.yml @@ -29,7 +29,6 @@ concurrency: env: PYTHONUNBUFFERED: "1" FORCE_COLOR: "1" - HF_TOKEN: ${{ secrets.HF_TOKEN }} TEST_MATRIX_OS: '["ubuntu-latest", "windows-latest", "macos-latest"]' TEST_MATRIX_PYTHON: '["3.10", "3.14"]' @@ -105,6 +104,8 @@ jobs: path: python-coverage-comment-action-huggingface_api.txt - name: Run integration tests + env: + HF_TOKEN: ${{ secrets.HF_TOKEN }} run: hatch run test:integration-cov-append-retry - name: Store combined coverage diff --git a/.github/workflows/jina.yml b/.github/workflows/jina.yml index 435bc5eedd..87727e1444 100644 --- a/.github/workflows/jina.yml +++ b/.github/workflows/jina.yml @@ -26,7 +26,6 @@ concurrency: cancel-in-progress: true env: - JINA_API_KEY: ${{ secrets.JINA_API_KEY }} PYTHONUNBUFFERED: "1" FORCE_COLOR: "1" TEST_MATRIX_OS: '["ubuntu-latest", "windows-latest", "macos-latest"]' @@ -105,6 +104,8 @@ jobs: path: python-coverage-comment-action-jina.txt - name: Run integration tests + env: + JINA_API_KEY: ${{ secrets.JINA_API_KEY }} run: hatch run test:integration-cov-append-retry - name: Store combined coverage diff --git a/.github/workflows/langfuse.yml b/.github/workflows/langfuse.yml index 0a96d720dd..30ad6a31bd 100644 --- a/.github/workflows/langfuse.yml +++ b/.github/workflows/langfuse.yml @@ -29,11 +29,6 @@ concurrency: env: PYTHONUNBUFFERED: "1" FORCE_COLOR: "1" - LANGFUSE_SECRET_KEY: ${{ secrets.LANGFUSE_SECRET_KEY }} - LANGFUSE_PUBLIC_KEY: ${{ secrets.LANGFUSE_PUBLIC_KEY }} - OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} - ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} - COHERE_API_KEY: ${{ secrets.COHERE_API_KEY }} TEST_MATRIX_OS: '["ubuntu-latest", "windows-latest", "macos-latest"]' TEST_MATRIX_PYTHON: '["3.10", "3.13"]' @@ -110,6 +105,12 @@ jobs: path: python-coverage-comment-action-langfuse.txt - name: Run integration tests + env: + LANGFUSE_SECRET_KEY: ${{ secrets.LANGFUSE_SECRET_KEY }} + LANGFUSE_PUBLIC_KEY: ${{ secrets.LANGFUSE_PUBLIC_KEY }} + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} + COHERE_API_KEY: ${{ secrets.COHERE_API_KEY }} run: hatch run test:integration-cov-append-retry - name: Store combined coverage diff --git a/.github/workflows/lara.yml b/.github/workflows/lara.yml index 75250d8c7e..bec2d3c461 100644 --- a/.github/workflows/lara.yml +++ b/.github/workflows/lara.yml @@ -25,8 +25,6 @@ concurrency: env: PYTHONUNBUFFERED: "1" FORCE_COLOR: "1" - LARA_ACCESS_KEY_ID: ${{ secrets.LARA_ACCESS_KEY_ID }} - LARA_ACCESS_KEY_SECRET: ${{ secrets.LARA_ACCESS_KEY_SECRET }} TEST_MATRIX_OS: '["ubuntu-latest", "windows-latest", "macos-latest"]' TEST_MATRIX_PYTHON: '["3.10", "3.14"]' @@ -103,6 +101,9 @@ jobs: path: python-coverage-comment-action-lara.txt - name: Run integration tests + env: + LARA_ACCESS_KEY_ID: ${{ secrets.LARA_ACCESS_KEY_ID }} + LARA_ACCESS_KEY_SECRET: ${{ secrets.LARA_ACCESS_KEY_SECRET }} run: hatch run test:integration-cov-append-retry - name: Store combined coverage diff --git a/.github/workflows/litellm.yml b/.github/workflows/litellm.yml index 4f358c844a..3c347a4ad1 100644 --- a/.github/workflows/litellm.yml +++ b/.github/workflows/litellm.yml @@ -29,7 +29,6 @@ concurrency: env: PYTHONUNBUFFERED: "1" FORCE_COLOR: "1" - OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} TEST_MATRIX_OS: '["ubuntu-latest", "windows-latest", "macos-latest"]' TEST_MATRIX_PYTHON: '["3.10", "3.14"]' @@ -106,6 +105,8 @@ jobs: path: python-coverage-comment-action-litellm.txt - name: Run integration tests + env: + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} run: hatch run test:integration-cov-append-retry - name: Store combined coverage diff --git a/.github/workflows/llama_cpp.yml b/.github/workflows/llama_cpp.yml index 6163230f3d..5562505604 100644 --- a/.github/workflows/llama_cpp.yml +++ b/.github/workflows/llama_cpp.yml @@ -28,7 +28,6 @@ concurrency: env: PYTHONUNBUFFERED: "1" FORCE_COLOR: "1" - HF_TOKEN: ${{ secrets.HF_TOKEN }} TEST_MATRIX_OS: '["ubuntu-latest", "windows-latest", "macos-latest"]' TEST_MATRIX_PYTHON: '["3.10", "3.14"]' @@ -105,6 +104,8 @@ jobs: path: python-coverage-comment-action-llama_cpp.txt - name: Run integration tests + env: + HF_TOKEN: ${{ secrets.HF_TOKEN }} run: hatch run test:integration-cov-append-retry - name: Store combined coverage diff --git a/.github/workflows/mcp.yml b/.github/workflows/mcp.yml index 89daf4fdd4..9fa682519d 100644 --- a/.github/workflows/mcp.yml +++ b/.github/workflows/mcp.yml @@ -29,8 +29,6 @@ concurrency: env: PYTHONUNBUFFERED: "1" FORCE_COLOR: "1" - BRAVE_API_KEY: ${{ secrets.BRAVE_API_KEY }} - OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} TEST_MATRIX_OS: '["ubuntu-latest", "macos-latest", "windows-latest"]' TEST_MATRIX_PYTHON: '["3.10", "3.14"]' @@ -123,6 +121,9 @@ jobs: - name: Run integration tests run: hatch run test:integration-cov-append-retry + env: + BRAVE_API_KEY: ${{ secrets.BRAVE_API_KEY }} + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} - name: Store combined coverage if: github.event_name == 'push' diff --git a/.github/workflows/mem0.yml b/.github/workflows/mem0.yml index f2604763f6..5f3aa25f04 100644 --- a/.github/workflows/mem0.yml +++ b/.github/workflows/mem0.yml @@ -29,7 +29,6 @@ concurrency: env: PYTHONUNBUFFERED: "1" FORCE_COLOR: "1" - MEM0_API_KEY: ${{ secrets.MEM0_API_KEY }} TEST_MATRIX_OS: '["ubuntu-latest", "windows-latest", "macos-latest"]' TEST_MATRIX_PYTHON: '["3.10", "3.14"]' @@ -107,6 +106,8 @@ jobs: - name: Run integration tests run: hatch run test:integration-cov-append-retry + env: + MEM0_API_KEY: ${{ secrets.MEM0_API_KEY }} - name: Store combined coverage if: github.event_name == 'push' diff --git a/.github/workflows/mistral.yml b/.github/workflows/mistral.yml index f215c8a780..3b62c48f44 100644 --- a/.github/workflows/mistral.yml +++ b/.github/workflows/mistral.yml @@ -29,7 +29,6 @@ concurrency: env: PYTHONUNBUFFERED: "1" FORCE_COLOR: "1" - MISTRAL_API_KEY: ${{ secrets.MISTRAL_API_KEY }} TEST_MATRIX_OS: '["ubuntu-latest", "windows-latest", "macos-latest"]' TEST_MATRIX_PYTHON: '["3.10", "3.14"]' @@ -107,6 +106,8 @@ jobs: - name: Run integration tests run: hatch run test:integration-cov-append-retry + env: + MISTRAL_API_KEY: ${{ secrets.MISTRAL_API_KEY }} - name: Store combined coverage if: github.event_name == 'push' @@ -128,6 +129,8 @@ jobs: # Since this integration inherits from OpenAIChatGenerator, we run ALL tests with Haystack main branch to catch regressions - name: Nightly - run tests with Haystack main branch if: github.event_name == 'schedule' + env: + MISTRAL_API_KEY: ${{ secrets.MISTRAL_API_KEY }} run: | hatch env prune hatch -e test env run -- uv pip install git+https://github.com/deepset-ai/haystack.git@main diff --git a/.github/workflows/mongodb_atlas.yml b/.github/workflows/mongodb_atlas.yml index 73b347cdf2..90bfde41a9 100644 --- a/.github/workflows/mongodb_atlas.yml +++ b/.github/workflows/mongodb_atlas.yml @@ -29,8 +29,6 @@ concurrency: env: PYTHONUNBUFFERED: "1" FORCE_COLOR: "1" - MONGO_CONNECTION_STRING: ${{ secrets.MONGO_CONNECTION_STRING }} - MONGO_CONNECTION_STRING_2: ${{ secrets.MONGO_CONNECTION_STRING_2 }} TEST_MATRIX_OS: '["ubuntu-latest", "windows-latest", "macos-latest"]' TEST_MATRIX_PYTHON: '["3.10", "3.14"]' @@ -103,6 +101,9 @@ jobs: - name: Run integration tests run: hatch run test:integration-cov-append-retry + env: + MONGO_CONNECTION_STRING: ${{ secrets.MONGO_CONNECTION_STRING }} + MONGO_CONNECTION_STRING_2: ${{ secrets.MONGO_CONNECTION_STRING_2 }} - name: Store combined coverage if: github.event_name == 'push' diff --git a/.github/workflows/nvidia.yml b/.github/workflows/nvidia.yml index 49b2e9f99b..4316591cbc 100644 --- a/.github/workflows/nvidia.yml +++ b/.github/workflows/nvidia.yml @@ -29,8 +29,6 @@ concurrency: env: PYTHONUNBUFFERED: "1" FORCE_COLOR: "1" - NVIDIA_API_KEY: ${{ secrets.NVIDIA_API_KEY }} - NVIDIA_CATALOG_API_KEY: ${{ secrets.NVIDIA_CATALOG_API_KEY }} TEST_MATRIX_OS: '["ubuntu-latest", "windows-latest", "macos-latest"]' TEST_MATRIX_PYTHON: '["3.10"]' @@ -108,6 +106,9 @@ jobs: - name: Run integration tests run: hatch run test:integration-cov-append-retry + env: + NVIDIA_API_KEY: ${{ secrets.NVIDIA_API_KEY }} + NVIDIA_CATALOG_API_KEY: ${{ secrets.NVIDIA_CATALOG_API_KEY }} - name: Store combined coverage if: github.event_name == 'push' @@ -129,6 +130,9 @@ jobs: # Since this integration inherits from OpenAIChatGenerator, we run ALL tests with Haystack main branch to catch regressions - name: Nightly - run tests with Haystack main branch if: github.event_name == 'schedule' + env: + NVIDIA_API_KEY: ${{ secrets.NVIDIA_API_KEY }} + NVIDIA_CATALOG_API_KEY: ${{ secrets.NVIDIA_CATALOG_API_KEY }} run: | hatch env prune hatch -e test env run -- uv pip install git+https://github.com/deepset-ai/haystack.git@main diff --git a/.github/workflows/openapi.yml b/.github/workflows/openapi.yml index 13be96b3b8..4d130b77fc 100644 --- a/.github/workflows/openapi.yml +++ b/.github/workflows/openapi.yml @@ -29,7 +29,6 @@ concurrency: env: PYTHONUNBUFFERED: "1" FORCE_COLOR: "1" - OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} TEST_MATRIX_OS: '["ubuntu-latest", "windows-latest", "macos-latest"]' TEST_MATRIX_PYTHON: '["3.10", "3.14"]' @@ -106,6 +105,8 @@ jobs: - name: Run integration tests run: hatch run test:integration-cov-append-retry + env: + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} - name: Store combined coverage if: github.event_name == 'push' diff --git a/.github/workflows/openrouter.yml b/.github/workflows/openrouter.yml index d357727234..54bed05aee 100644 --- a/.github/workflows/openrouter.yml +++ b/.github/workflows/openrouter.yml @@ -29,7 +29,6 @@ concurrency: env: PYTHONUNBUFFERED: "1" FORCE_COLOR: "1" - OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }} TEST_MATRIX_OS: '["ubuntu-latest", "windows-latest", "macos-latest"]' TEST_MATRIX_PYTHON: '["3.10", "3.14"]' @@ -106,6 +105,8 @@ jobs: - name: Run integration tests run: hatch run test:integration-cov-append-retry + env: + OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }} - name: Store combined coverage if: github.event_name == 'push' @@ -127,6 +128,8 @@ jobs: # Since this integration inherits from OpenAIChatGenerator, we run ALL tests with Haystack main branch to catch regressions - name: Nightly - run tests with Haystack main branch if: github.event_name == 'schedule' + env: + OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }} run: | hatch env prune hatch -e test env run -- uv pip install git+https://github.com/deepset-ai/haystack.git@main diff --git a/.github/workflows/optimum.yml b/.github/workflows/optimum.yml index 704f106832..b253e448b6 100644 --- a/.github/workflows/optimum.yml +++ b/.github/workflows/optimum.yml @@ -29,7 +29,6 @@ concurrency: env: PYTHONUNBUFFERED: "1" FORCE_COLOR: "1" - HF_TOKEN: ${{ secrets.HF_TOKEN }} TEST_MATRIX_OS: '["ubuntu-latest", "windows-latest", "macos-latest"]' TEST_MATRIX_PYTHON: '["3.10", "3.14"]' @@ -106,6 +105,8 @@ jobs: path: python-coverage-comment-action-optimum.txt - name: Run integration tests + env: + HF_TOKEN: ${{ secrets.HF_TOKEN }} run: hatch run test:integration-cov-append-retry - name: Store combined coverage diff --git a/.github/workflows/orcarouter.yml b/.github/workflows/orcarouter.yml index f90d12ec6e..a171e7204f 100644 --- a/.github/workflows/orcarouter.yml +++ b/.github/workflows/orcarouter.yml @@ -29,7 +29,6 @@ concurrency: env: PYTHONUNBUFFERED: "1" FORCE_COLOR: "1" - ORCAROUTER_API_KEY: ${{ secrets.ORCAROUTER_API_KEY }} TEST_MATRIX_OS: '["ubuntu-latest", "windows-latest", "macos-latest"]' TEST_MATRIX_PYTHON: '["3.10", "3.14"]' @@ -105,6 +104,8 @@ jobs: path: python-coverage-comment-action-orcarouter.txt - name: Run integration tests + env: + ORCAROUTER_API_KEY: ${{ secrets.ORCAROUTER_API_KEY }} run: hatch run test:integration-cov-append-retry - name: Store combined coverage @@ -127,6 +128,8 @@ jobs: # Since this integration inherits from OpenAIChatGenerator, we run ALL tests with Haystack main branch to catch regressions - name: Nightly - run tests with Haystack main branch if: github.event_name == 'schedule' + env: + ORCAROUTER_API_KEY: ${{ secrets.ORCAROUTER_API_KEY }} run: | hatch env prune hatch -e test env run -- uv pip install git+https://github.com/deepset-ai/haystack.git@main diff --git a/.github/workflows/paddleocr.yml b/.github/workflows/paddleocr.yml index c56c559626..11afb154c8 100644 --- a/.github/workflows/paddleocr.yml +++ b/.github/workflows/paddleocr.yml @@ -29,8 +29,6 @@ concurrency: env: PYTHONUNBUFFERED: "1" FORCE_COLOR: "1" - PADDLEOCR_ACCESS_TOKEN: ${{ secrets.PADDLEOCR_ACCESS_TOKEN }} - PADDLEOCR_BASE_URL: ${{ secrets.PADDLEOCR_BASE_URL }} TEST_MATRIX_OS: '["ubuntu-latest", "windows-latest", "macos-latest"]' TEST_MATRIX_PYTHON: '["3.10", "3.12"]' @@ -107,6 +105,9 @@ jobs: path: python-coverage-comment-action-paddleocr.txt - name: Run integration tests + env: + PADDLEOCR_ACCESS_TOKEN: ${{ secrets.PADDLEOCR_ACCESS_TOKEN }} + PADDLEOCR_BASE_URL: ${{ secrets.PADDLEOCR_BASE_URL }} run: hatch run test:integration-cov-append-retry - name: Store combined coverage diff --git a/.github/workflows/perplexity.yml b/.github/workflows/perplexity.yml index 7ad3a2c1fb..d38e9eec76 100644 --- a/.github/workflows/perplexity.yml +++ b/.github/workflows/perplexity.yml @@ -29,7 +29,6 @@ concurrency: env: PYTHONUNBUFFERED: "1" FORCE_COLOR: "1" - PERPLEXITY_API_KEY: ${{ secrets.PERPLEXITY_API_KEY }} TEST_MATRIX_OS: '["ubuntu-latest", "windows-latest", "macos-latest"]' TEST_MATRIX_PYTHON: '["3.10", "3.14"]' @@ -103,6 +102,8 @@ jobs: path: python-coverage-comment-action-perplexity.txt - name: Run integration tests + env: + PERPLEXITY_API_KEY: ${{ secrets.PERPLEXITY_API_KEY }} run: hatch run test:integration-cov-append-retry - name: Store combined coverage diff --git a/.github/workflows/pinecone.yml b/.github/workflows/pinecone.yml index 40fff56746..453307e92e 100644 --- a/.github/workflows/pinecone.yml +++ b/.github/workflows/pinecone.yml @@ -29,7 +29,6 @@ concurrency: env: PYTHONUNBUFFERED: "1" FORCE_COLOR: "1" - PINECONE_API_KEY: ${{ secrets.PINECONE_API_KEY }} jobs: compute-test-matrix: @@ -107,6 +106,7 @@ jobs: - name: Run integration tests env: INDEX_NAME: ${{ matrix.INDEX_NAME }} + PINECONE_API_KEY: ${{ secrets.PINECONE_API_KEY }} run: hatch run test:integration-cov-append-retry - name: Store combined coverage diff --git a/.github/workflows/ragas.yml b/.github/workflows/ragas.yml index 973116f049..b633a610bc 100644 --- a/.github/workflows/ragas.yml +++ b/.github/workflows/ragas.yml @@ -29,7 +29,6 @@ concurrency: env: PYTHONUNBUFFERED: "1" FORCE_COLOR: "1" - OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} TEST_MATRIX_OS: '["ubuntu-latest", "windows-latest", "macos-latest"]' TEST_MATRIX_PYTHON: '["3.10", "3.14"]' @@ -106,6 +105,8 @@ jobs: path: python-coverage-comment-action-ragas.txt - name: Run integration tests + env: + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} run: hatch run test:integration-cov-append-retry - name: Store combined coverage diff --git a/.github/workflows/searchapi.yml b/.github/workflows/searchapi.yml index df20bfa6bb..ccef94a237 100644 --- a/.github/workflows/searchapi.yml +++ b/.github/workflows/searchapi.yml @@ -29,7 +29,6 @@ concurrency: env: PYTHONUNBUFFERED: "1" FORCE_COLOR: "1" - SEARCHAPI_API_KEY: ${{ secrets.SEARCHAPI_API_KEY }} TEST_MATRIX_OS: '["ubuntu-latest", "windows-latest", "macos-latest"]' TEST_MATRIX_PYTHON: '["3.10", "3.14"]' @@ -105,6 +104,8 @@ jobs: path: python-coverage-comment-action-searchapi.txt - name: Run integration tests + env: + SEARCHAPI_API_KEY: ${{ secrets.SEARCHAPI_API_KEY }} run: hatch run test:integration-cov-append-retry - name: Store combined coverage diff --git a/.github/workflows/sentence_transformers.yml b/.github/workflows/sentence_transformers.yml index aca547c377..1061956c83 100644 --- a/.github/workflows/sentence_transformers.yml +++ b/.github/workflows/sentence_transformers.yml @@ -31,8 +31,6 @@ env: FORCE_COLOR: "1" TEST_MATRIX_OS: '["ubuntu-latest", "windows-latest", "macos-latest"]' TEST_MATRIX_PYTHON: '["3.10", "3.14"]' - HF_TOKEN: ${{ secrets.HF_TOKEN }} - OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} jobs: compute-test-matrix: @@ -106,6 +104,9 @@ jobs: path: python-coverage-comment-action-sentence_transformers.txt - name: Run integration tests + env: + HF_TOKEN: ${{ secrets.HF_TOKEN }} + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} run: hatch run test:integration-cov-append-retry - name: Store combined coverage diff --git a/.github/workflows/serperdev.yml b/.github/workflows/serperdev.yml index 19547d2856..b1bdf89a08 100644 --- a/.github/workflows/serperdev.yml +++ b/.github/workflows/serperdev.yml @@ -29,7 +29,6 @@ concurrency: env: PYTHONUNBUFFERED: "1" FORCE_COLOR: "1" - SERPERDEV_API_KEY: ${{ secrets.SERPERDEV_API_KEY }} TEST_MATRIX_OS: '["ubuntu-latest", "windows-latest", "macos-latest"]' TEST_MATRIX_PYTHON: '["3.10", "3.14"]' @@ -105,6 +104,8 @@ jobs: path: python-coverage-comment-action-serperdev.txt - name: Run integration tests + env: + SERPERDEV_API_KEY: ${{ secrets.SERPERDEV_API_KEY }} run: hatch run test:integration-cov-append-retry - name: Store combined coverage diff --git a/.github/workflows/stackit.yml b/.github/workflows/stackit.yml index 0cc082bf0b..aac7e93f96 100644 --- a/.github/workflows/stackit.yml +++ b/.github/workflows/stackit.yml @@ -29,7 +29,6 @@ concurrency: env: PYTHONUNBUFFERED: "1" FORCE_COLOR: "1" - STACKIT_API_KEY: ${{ secrets.STACKIT_API_KEY }} TEST_MATRIX_OS: '["ubuntu-latest", "windows-latest", "macos-latest"]' TEST_MATRIX_PYTHON: '["3.10", "3.14"]' @@ -105,6 +104,8 @@ jobs: path: python-coverage-comment-action-stackit.txt - name: Run integration tests + env: + STACKIT_API_KEY: ${{ secrets.STACKIT_API_KEY }} run: hatch run test:integration-cov-append-retry - name: Store combined coverage @@ -127,6 +128,8 @@ jobs: # Since this integration inherits from OpenAIChatGenerator, we run ALL tests with Haystack main branch to catch regressions - name: Nightly - run tests with Haystack main branch if: github.event_name == 'schedule' + env: + STACKIT_API_KEY: ${{ secrets.STACKIT_API_KEY }} run: | hatch env prune hatch -e test env run -- uv pip install git+https://github.com/deepset-ai/haystack.git@main diff --git a/.github/workflows/togetherai.yml b/.github/workflows/togetherai.yml index 56fc8be74a..1381ea4338 100644 --- a/.github/workflows/togetherai.yml +++ b/.github/workflows/togetherai.yml @@ -29,7 +29,6 @@ concurrency: env: PYTHONUNBUFFERED: "1" FORCE_COLOR: "1" - TOGETHER_API_KEY: ${{ secrets.TOGETHER_AI_API_KEY }} TEST_MATRIX_OS: '["ubuntu-latest", "windows-latest", "macos-latest"]' TEST_MATRIX_PYTHON: '["3.10", "3.14"]' @@ -105,6 +104,8 @@ jobs: path: python-coverage-comment-action-togetherai.txt - name: Run integration tests + env: + TOGETHER_API_KEY: ${{ secrets.TOGETHER_AI_API_KEY }} run: hatch run test:integration-cov-append-retry - name: Store combined coverage @@ -127,6 +128,8 @@ jobs: # Since this integration inherits from OpenAIChatGenerator, we run ALL tests with Haystack main branch to catch regressions - name: Nightly - run tests with Haystack main branch if: github.event_name == 'schedule' + env: + TOGETHER_API_KEY: ${{ secrets.TOGETHER_AI_API_KEY }} run: | hatch env prune hatch -e test env run -- uv pip install git+https://github.com/deepset-ai/haystack.git@main diff --git a/.github/workflows/transformers.yml b/.github/workflows/transformers.yml index c6c151ac70..ac322ef73d 100644 --- a/.github/workflows/transformers.yml +++ b/.github/workflows/transformers.yml @@ -29,7 +29,6 @@ concurrency: env: PYTHONUNBUFFERED: "1" FORCE_COLOR: "1" - HF_TOKEN: ${{ secrets.HF_TOKEN }} TEST_MATRIX_OS: '["ubuntu-latest", "windows-latest", "macos-latest"]' TEST_MATRIX_PYTHON: '["3.10", "3.14"]' @@ -105,6 +104,8 @@ jobs: path: python-coverage-comment-action-transformers.txt - name: Run integration tests + env: + HF_TOKEN: ${{ secrets.HF_TOKEN }} run: hatch run test:integration-cov-append-retry - name: Store combined coverage diff --git a/.github/workflows/twelvelabs.yml b/.github/workflows/twelvelabs.yml index 3f17db5fdc..1216da8f7d 100644 --- a/.github/workflows/twelvelabs.yml +++ b/.github/workflows/twelvelabs.yml @@ -29,7 +29,6 @@ concurrency: env: PYTHONUNBUFFERED: "1" FORCE_COLOR: "1" - TWELVELABS_API_KEY: "${{ secrets.TWELVELABS_API_KEY }}" TEST_MATRIX_OS: '["ubuntu-latest", "windows-latest", "macos-latest"]' TEST_MATRIX_PYTHON: '["3.10", "3.14"]' @@ -105,6 +104,8 @@ jobs: path: python-coverage-comment-action-twelvelabs.txt - name: Run integration tests + env: + TWELVELABS_API_KEY: "${{ secrets.TWELVELABS_API_KEY }}" run: hatch run test:integration-cov-append-retry - name: Store combined coverage diff --git a/.github/workflows/watsonx.yml b/.github/workflows/watsonx.yml index ee0124cca9..e872b0882e 100644 --- a/.github/workflows/watsonx.yml +++ b/.github/workflows/watsonx.yml @@ -29,8 +29,6 @@ concurrency: env: PYTHONUNBUFFERED: "1" FORCE_COLOR: "1" - WATSONX_API_KEY: ${{ secrets.WATSONX_API_KEY }} - WATSONX_PROJECT_ID: ${{ secrets.WATSONX_PROJECT_ID }} TEST_MATRIX_OS: '["ubuntu-latest", "windows-latest", "macos-latest"]' TEST_MATRIX_PYTHON: '["3.10", "3.13"]' @@ -107,6 +105,9 @@ jobs: path: python-coverage-comment-action-watsonx.txt - name: Run integration tests + env: + WATSONX_API_KEY: ${{ secrets.WATSONX_API_KEY }} + WATSONX_PROJECT_ID: ${{ secrets.WATSONX_PROJECT_ID }} run: hatch run test:integration-cov-append-retry - name: Store combined coverage diff --git a/.github/workflows/weave.yml b/.github/workflows/weave.yml index 2f00003982..e19f8fb96a 100644 --- a/.github/workflows/weave.yml +++ b/.github/workflows/weave.yml @@ -29,7 +29,6 @@ concurrency: env: PYTHONUNBUFFERED: "1" FORCE_COLOR: "1" - WANDB_API_KEY: ${{ secrets.WANDB_API_KEY }} TEST_MATRIX_OS: '["ubuntu-latest", "windows-latest", "macos-latest"]' TEST_MATRIX_PYTHON: '["3.10", "3.14"]' @@ -101,6 +100,8 @@ jobs: path: python-coverage-comment-action-weave.txt - name: Run integration tests + env: + WANDB_API_KEY: ${{ secrets.WANDB_API_KEY }} run: hatch run test:integration-cov-append-retry - name: Store combined coverage diff --git a/.github/workflows/whisper.yml b/.github/workflows/whisper.yml index 75ee742104..19e64b42f6 100644 --- a/.github/workflows/whisper.yml +++ b/.github/workflows/whisper.yml @@ -29,7 +29,6 @@ concurrency: env: PYTHONUNBUFFERED: "1" FORCE_COLOR: "1" - OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} TEST_MATRIX_OS: '["ubuntu-latest", "windows-latest", "macos-latest"]' TEST_MATRIX_PYTHON: '["3.10", "3.14"]' @@ -115,6 +114,8 @@ jobs: run: brew install ffmpeg - name: Run integration tests + env: + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} run: hatch run test:integration-cov-append-retry - name: Store combined coverage diff --git a/integrations/arangodb/src/haystack_integrations/document_stores/arangodb/document_store.py b/integrations/arangodb/src/haystack_integrations/document_stores/arangodb/document_store.py index 95baf2386e..9825718171 100644 --- a/integrations/arangodb/src/haystack_integrations/document_stores/arangodb/document_store.py +++ b/integrations/arangodb/src/haystack_integrations/document_stores/arangodb/document_store.py @@ -3,6 +3,7 @@ # SPDX-License-Identifier: Apache-2.0 import dataclasses +import re from contextlib import suppress from typing import Any, Literal, cast @@ -30,6 +31,21 @@ _VECTOR_INDEX_NAME = "haystack_vector_index" +# ArangoDB "traditional" collection naming rules: start with a letter, followed by letters, +# digits, underscores, or dashes; at most 256 characters. The collection name is interpolated +# directly into AQL queries (it cannot be a bind parameter), so it is validated against this +# allowlist to prevent AQL injection. +_SAFE_COLLECTION_NAME = re.compile(r"^[A-Za-z][A-Za-z0-9_-]{0,255}$") + + +def _validate_collection_name(collection_name: str) -> None: + if not _SAFE_COLLECTION_NAME.match(collection_name): + msg = ( + f"Invalid collection_name {collection_name!r}. Must start with a letter and contain only " + "letters, digits, underscores, or dashes (max 256 characters)." + ) + raise ValueError(msg) + def _doc_to_arango(doc: Document) -> dict[str, Any]: d = doc.to_dict(flatten=False) @@ -89,12 +105,15 @@ def __init__( :param username: ArangoDB username as a `Secret`. Defaults to `ARANGO_USERNAME` env var, falling back to `root` if the variable is not set. :param password: ArangoDB password as a `Secret`. Defaults to `ARANGO_PASSWORD` env var. - :param collection_name: Name of the collection to store documents in. + :param collection_name: Name of the collection to store documents in. Must start with a letter + and contain only letters, digits, underscores, or dashes (max 256 characters). :param embedding_dimension: Dimensionality of document embeddings. :param recreate_collection: If `True`, drop and recreate the collection on startup. :param similarity_function: Vector similarity function to use for embedding retrieval. One of `"cosine"` (default), `"dot_product"`, or `"l2"`. + :raises ValueError: If `collection_name` is not a valid ArangoDB collection identifier. """ + _validate_collection_name(collection_name) self.host = host self.database = database self.username = username diff --git a/integrations/arangodb/tests/test_document_store.py b/integrations/arangodb/tests/test_document_store.py index b711fbdd93..69cc972735 100644 --- a/integrations/arangodb/tests/test_document_store.py +++ b/integrations/arangodb/tests/test_document_store.py @@ -30,6 +30,17 @@ def _make_store(**kwargs) -> ArangoDocumentStore: ) +def _make_store_named(collection_name: str) -> ArangoDocumentStore: + return ArangoDocumentStore( + host="http://localhost:8529", + database="haystack", + username=Secret.from_token("root"), + password=Secret.from_token("test-password"), + collection_name=collection_name, + embedding_dimension=3, + ) + + def _mock_db(store: ArangoDocumentStore, collection_docs: list[dict] | None = None) -> MagicMock: mock_col = MagicMock() mock_col.count.return_value = len(collection_docs or []) @@ -68,6 +79,45 @@ def test_init_custom(self): assert store.similarity_function == "dot_product" +class TestArangoDocumentStoreCollectionNameValidation: + """`collection_name` is interpolated into AQL, so it must be validated up front.""" + + @pytest.mark.parametrize( + "collection_name", + [ + pytest.param("docs` FOR d IN secrets RETURN d //", id="aql_injection"), + pytest.param("docs secrets", id="whitespace"), + pytest.param("docs;drop", id="semicolon"), + pytest.param("docs`backtick", id="backtick"), + pytest.param('docs"quote', id="double_quote"), + pytest.param("docs\nsecrets", id="newline"), + pytest.param("1docs", id="leading_digit"), + pytest.param("_docs", id="leading_underscore"), + pytest.param("-docs", id="leading_dash"), + pytest.param("", id="empty"), + pytest.param("d" * 257, id="too_long"), + ], + ) + def test_init_rejects_invalid_collection_name(self, collection_name): + with pytest.raises(ValueError, match="Invalid collection_name"): + _make_store_named(collection_name) + + @pytest.mark.parametrize( + "collection_name", + [ + pytest.param("docs", id="lowercase"), + pytest.param("Docs", id="uppercase"), + pytest.param("test_docs", id="underscore"), + pytest.param("test-docs", id="dash"), + pytest.param("docs123", id="digits"), + pytest.param("d", id="single_char"), + pytest.param("d" * 256, id="max_length"), + ], + ) + def test_init_accepts_valid_collection_name(self, collection_name): + assert _make_store_named(collection_name).collection_name == collection_name + + class TestArangoDocumentStoreSerialization: def test_to_dict(self, monkeypatch): monkeypatch.setenv("ARANGO_PASSWORD", "pw") diff --git a/integrations/nvidia/src/haystack_integrations/utils/nvidia/nim_backend.py b/integrations/nvidia/src/haystack_integrations/utils/nvidia/nim_backend.py index a1033d1135..8fc03e2c95 100644 --- a/integrations/nvidia/src/haystack_integrations/utils/nvidia/nim_backend.py +++ b/integrations/nvidia/src/haystack_integrations/utils/nvidia/nim_backend.py @@ -19,6 +19,11 @@ REQUEST_TIMEOUT = 60.0 +def _error_text(error: requests.HTTPError) -> str: + """Return the response body of a failed request, falling back to the error itself if there is no response.""" + return error.response.text if error.response is not None else str(error) + + class NimBackend: def __init__( self, @@ -89,8 +94,9 @@ def embed(self, texts: list[str]) -> tuple[list[list[float]], dict[str, Any]]: ) res.raise_for_status() except requests.HTTPError as e: - logger.error("Error when calling NIM embedding endpoint: Error - {error}", error=e.response.text) - msg = f"Failed to query embedding endpoint: Error - {e.response.text}" + error_text = _error_text(e) + logger.error("Error when calling NIM embedding endpoint: Error - {error}", error=error_text) + msg = f"Failed to query embedding endpoint: Error - {error_text}" raise ValueError(msg) from e data = res.json() @@ -123,8 +129,9 @@ def generate(self, prompt: str) -> tuple[list[str], list[dict[str, Any]]]: ) res.raise_for_status() except requests.HTTPError as e: - logger.error("Error when calling NIM chat completion endpoint: Error - {error}", error=e.response.text) - msg = f"Failed to query chat completion endpoint: Error - {e.response.text}" + error_text = _error_text(e) + logger.error("Error when calling NIM chat completion endpoint: Error - {error}", error=error_text) + msg = f"Failed to query chat completion endpoint: Error - {error_text}" raise ValueError(msg) from e completions = res.json() @@ -194,8 +201,9 @@ def rank(self, query_text: str, document_texts: list[str]) -> list[dict[str, Any ) res.raise_for_status() except requests.HTTPError as e: - logger.error("Error when calling NIM ranking endpoint: Error - {error}", error=e.response.text) - msg = f"Failed to rank endpoint: Error - {e.response.text}" + error_text = _error_text(e) + logger.error("Error when calling NIM ranking endpoint: Error - {error}", error=error_text) + msg = f"Failed to rank endpoint: Error - {error_text}" raise ValueError(msg) from e data = res.json() diff --git a/uv.toml b/uv.toml index 44fc40ebdb..9797ed35e7 100644 --- a/uv.toml +++ b/uv.toml @@ -1,7 +1,7 @@ -# Exclude package versions published within the last 24 hours to protect against supply chain +# Exclude package versions published within the last 7 days to protect against supply chain # attacks via compromised dependencies. uv resolves this relative to the current clock at # install/lock time, so no manual date updates are needed. -exclude-newer = "24 hours" +exclude-newer = "7 days" # first-party dependencies [exclude-newer-package]