# Python package # Create and test a Python package on multiple Python versions. # Add steps that analyze code, save the dist with the build record, publish to a PyPI-compatible index, and more: # https://docs.microsoft.com/azure/devops/pipelines/languages/python trigger: tags: include: - "*" branches: include: - "master" - "release/*" - "refs/tags/*" schedules: - cron: "0 0 * * *" # At the end of every day displayName: Daily midnight testing branches: include: - "master" pr: branches: include: - "master" - "release/*" paths: include: - ".actions/*" - ".azure/app-cloud-e2e.yml" - "src/lightning/__about__.py" - "src/lightning/__init__.py" - "src/lightning/__main__.py" - "src/lightning/__setup__.py" - "src/lightning/__version__.py" - "src/lightning/app/**" - "src/lightning_app/*" - "examples/app/**" - "requirements/app/**" - "tests/integrations_app/**" - "setup.py" exclude: - "!tests/integrations_app/flagship/**" - "requirements/*/docs.txt" - "*.md" - "**/*.md" # variables are automatically exported as environment variables so this will override pip's default cache dir variables: - name: pip_cache_dir value: $(Pipeline.Workspace)/.pip - name: local_id value: $(Build.BuildId) - name: video_artifact_dir value: ./videos jobs: - job: test_e2e pool: "azure-cpus" container: # see all available tags: https://mcr.microsoft.com/en-us/product/playwright/python/tags image: mcr.microsoft.com/playwright/python:v1.38.0-focal options: "--shm-size=4gb" strategy: matrix: "App: v0_app": name: "v0_app" dir: "public" "App: boring_app": name: "boring_app" dir: "public" "App: template_streamlit_ui": name: "template_streamlit_ui" dir: "public" "App: template_react_ui": name: "template_react_ui" dir: "public" # 'App: template_jupyterlab': # TODO: clarify where these files lives # name: "template_jupyterlab" "App: installation_commands_app": name: "installation_commands_app" dir: "public" "App: drive": name: "drive" dir: "public" "App: payload": name: "payload" dir: "public" "App: commands_and_api": name: "commands_and_api" dir: "public" "App: quick_start": name: "quick_start" dir: "public" "App: idle_timeout": name: "idle_timeout" dir: "local" "App: collect_failures": name: "collect_failures" dir: "local" "App: custom_work_dependencies": name: "custom_work_dependencies" dir: "local" timeoutInMinutes: "15" cancelTimeoutInMinutes: "1" # values: https://docs.microsoft.com/en-us/azure/devops/pipelines/process/phases?view=azure-devops&tabs=yaml#workspace workspace: clean: all variables: FREEZE_REQUIREMENTS: "1" HEADLESS: "1" PACKAGE_LIGHTNING: "1" CLOUD: "1" VIDEO_LOCATION: $(video_artifact_dir) PR_NUMBER: $(local_id) TEST_APP_NAME: $(name) TEST_APP_FOLDER: $(dir) HAR_LOCATION: "./artifacts/hars" SLOW_MO: "50" LIGHTNING_DEBUG: "1" steps: - script: echo '##vso[task.setvariable variable=local_id]$(System.PullRequest.PullRequestNumber)' displayName: "Set id for this PR" condition: eq(variables['Build.Reason'], 'PullRequest') - bash: | whoami mkdir -p "$(video_artifact_dir)/$(name)" printf "local id: $(local_id)\n" python --version pip --version echo "allow fail: ${{ in(variables['name'], 'quick_start', 'template_react_ui') }}" displayName: "Info" # TODO: we are testing it as `lightning`, so add also version for `lightning_app` - bash: | pip install -e .[app-dev] \ -f https://download.pytorch.org/whl/cpu/torch_stable.html displayName: "Install Lightning & dependencies" - bash: python -m playwright install # --with-deps displayName: "Install Playwright system dependencies" # The magic happens here it doesn't need to install the quick start dependencies. # This test is very important to test the main user story of lightning app. # It also e2e tests running on cloud without installing dependencies. - bash: | git clone https://github.com/Lightning-AI/lightning-quick-start examples/app/quick-start # without succeeded this could run even if the job has already failed condition: and(succeeded(), eq(variables['name'], 'quick_start')) displayName: "Clone Quick start Repo" - bash: | git clone https://github.com/Lightning-AI/lightning-template-react examples/app/template_react_ui # without succeeded this could run even if the job has already failed condition: and(succeeded(), eq(variables['name'], 'template_react_ui')) displayName: "Clone Template React UI Repo" # Replace imports to use `lightning` instead of `lightning_app` since we install lightning only ATM - bash: | pip install -q -r .actions/requirements.txt python .actions/assistant.py copy_replace_imports \ --source_dir="./examples" --source_import="lightning_app" --target_import="lightning.app" displayName: "Adjust examples" - bash: pip --version && pip list displayName: "List pip dependency" - bash: | ls -l examples/app/$(TEST_APP_NAME) echo ${TEST_FILE} python -m pytest ${TEST_FILE}::test_$(TEST_APP_NAME)_example_cloud \ --timeout=360 --capture=no -v --color=yes env: TEST_FILE: tests/integrations_app/$(TEST_APP_FOLDER)/test_$(TEST_APP_NAME).py #LAI_USER: $(LAI_USER) # for STAGING #LAI_PASS: $(LAI_PASS) # for STAGING LIGHTNING_USER_ID: $(LIGHTNING_USER_ID_PROD) LIGHTNING_API_KEY: $(LIGHTNING_API_KEY_PROD) LIGHTNING_USERNAME: $(LIGHTNING_USERNAME_PROD) LIGHTNING_CLOUD_URL: $(LIGHTNING_CLOUD_URL_PROD) # Todo: investigate why these apps are failing continueOnError: ${{ in(variables['name'], 'quick_start', 'template_react_ui') }} displayName: "Run the tests" - task: PublishPipelineArtifact@1 condition: failed() inputs: path: "$(video_artifact_dir)/$(name)" artifactName: $(name) publishLocation: "pipeline" displayName: "Publish videos" - bash: | time python -c "from lightning.app import testing; testing.delete_cloud_lightning_apps()" condition: always() continueOnError: "true" timeoutInMinutes: "3" env: #LAI_USER: $(LAI_USER) # for STAGING #LAI_PASS: $(LAI_PASS) # for STAGING LIGHTNING_USER_ID: $(LIGHTNING_USER_ID_PROD) LIGHTNING_API_KEY: $(LIGHTNING_API_KEY_PROD) LIGHTNING_USERNAME: $(LIGHTNING_USERNAME_PROD) LIGHTNING_CLOUD_URL: $(LIGHTNING_CLOUD_URL_PROD) displayName: "Clean Previous Apps"