diff --git a/.github/workflows/smoke-tests.yml b/.github/workflows/smoke-tests.yml new file mode 100644 index 000000000..418a8efe2 --- /dev/null +++ b/.github/workflows/smoke-tests.yml @@ -0,0 +1,104 @@ +name: Smoke Tests + +on: + pull_request: + types: [opened, labeled, synchronize, reopened] + workflow_dispatch: + +jobs: + smoke-tests: + if: contains(github.event.pull_request.labels.*.name, 'smoke-test') + name: "Smoke Tests (No API Keys)" + runs-on: ubuntu-latest + timeout-minutes: 20 + + steps: + - name: Checkout PR + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Set up Python 3.12 + uses: actions/setup-python@v4 + with: + python-version: "3.12" + + - name: Install uv + uses: astral-sh/setup-uv@v3 + with: + version: "latest" + + - name: Install backend dependencies + run: | + uv sync --dev + + - name: Run backend smoke tests (critical tests only) + run: | + uv run pytest \ + src/backend/tests/unit/test_database.py \ + src/backend/tests/unit/test_login.py \ + src/backend/tests/unit/api/v1/test_validate.py \ + src/backend/tests/unit/test_endpoints.py \ + src/backend/tests/unit/api/v1/test_flows.py \ + src/backend/tests/unit/graph/test_graph.py \ + src/backend/tests/unit/services/flow/test_flow_runner.py \ + src/backend/tests/unit/test_chat_endpoint.py \ + src/backend/tests/unit/api/v1/test_api_key.py \ + src/backend/tests/unit/api/v1/test_endpoints.py \ + src/backend/tests/unit/components/languagemodels/test_openai_model.py \ + src/backend/tests/unit/components/agents/test_agent_component.py \ + src/backend/tests/unit/services/tracing/test_tracing_service.py \ + src/backend/tests/unit/custom/component/test_component_instance_attributes.py \ + src/backend/tests/unit/schema/test_schema_message.py \ + -m 'not api_key_required' \ + --tb=short \ + --maxfail=5 \ + -v + env: + LANGFLOW_SUPERUSER: admin + LANGFLOW_SUPERUSER_PASSWORD: 123456 + + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: "21" + cache: "npm" + cache-dependency-path: src/frontend/package-lock.json + + - name: Install frontend dependencies + run: | + cd src/frontend + npm ci + + - name: Run frontend smoke tests (unit tests only) + run: | + cd src/frontend + CI=true npx jest --ci --watchAll=false --passWithNoTests + env: + NODE_ENV: test + + - name: Comment on PR with results + if: always() + uses: actions/github-script@v6 + with: + script: | + const conclusion = '${{ job.status }}'; + const emoji = conclusion === 'success' ? '✅' : '❌'; + const status = conclusion === 'success' ? 'passed' : 'failed'; + + const comment = `${emoji} **Smoke tests ${status}** + + Critical functionality validated (~5-8 minutes): + + - **Backend**: 10 essential test files (imports, schema, serialization, core utils) + - **Frontend**: Unit tests only (components, utilities) + - **Coverage**: Core functionality without external dependencies + + View details in the [Actions tab](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}).`; + + await github.rest.issues.createComment({ + issue_number: context.payload.pull_request.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: comment + }); \ No newline at end of file diff --git a/src/backend/tests/unit/test_initial_setup.py b/src/backend/tests/unit/test_initial_setup.py index 8657b5e0d..dfa7a60e7 100644 --- a/src/backend/tests/unit/test_initial_setup.py +++ b/src/backend/tests/unit/test_initial_setup.py @@ -18,6 +18,7 @@ from langflow.initial_setup.setup import ( update_projects_components_with_latest_component_versions, ) from langflow.interface.components import aget_all_types_dict +from langflow.services.auth.utils import create_super_user from langflow.services.database.models import Flow from langflow.services.database.models.folder.model import Folder from langflow.services.deps import get_settings_service, session_scope @@ -238,6 +239,14 @@ async def test_load_bundles_from_urls(): ] settings_service.auth_settings.AUTO_LOGIN = True + # Create a superuser in the test database since load_bundles_from_urls requires one + async with session_scope() as session: + await create_super_user( + username=settings_service.auth_settings.SUPERUSER, + password=settings_service.auth_settings.SUPERUSER_PASSWORD, + db=session, + ) + temp_dirs, components_paths = await load_bundles_from_urls() try: