diff --git a/eng/ci/public-build.yml b/eng/ci/public-build.yml index 69ae8576f..17d8000c3 100644 --- a/eng/ci/public-build.yml +++ b/eng/ci/public-build.yml @@ -60,6 +60,12 @@ extends: PROJECT_DIRECTORY: 'workers' # Skip the build stage for SDK and Extensions release branches. This stage will fail because pyproject.toml contains the updated (and unreleased) library version condition: and(eq(variables.isSdkRelease, false), eq(variables.isExtensionsRelease, false), eq(variables['USETESTPYTHONSDK'], false), eq(variables['USETESTPYTHONEXTENSIONS'], false)) + - stage: CheckPythonWorkerDependencies + dependsOn: BuildPythonWorker + jobs: + - template: /eng/templates/jobs/ci-dependency-check.yml@self + parameters: + PoolName: 1es-pool-azfunc-public - stage: RunWorkerUnitTests dependsOn: BuildPythonWorker jobs: diff --git a/eng/templates/jobs/ci-dependency-check.yml b/eng/templates/jobs/ci-dependency-check.yml new file mode 100644 index 000000000..3ce00f954 --- /dev/null +++ b/eng/templates/jobs/ci-dependency-check.yml @@ -0,0 +1,81 @@ +jobs: + - job: "TestPython" + displayName: "Run Dependency Checks" + + pool: + name: ${{ parameters.PoolName }} + image: 1es-ubuntu-22.04 + os: linux + + strategy: + matrix: + Python39: + PYTHON_VERSION: '3.9' + Python310: + PYTHON_VERSION: '3.10' + Python311: + PYTHON_VERSION: '3.11' + Python312: + PYTHON_VERSION: '3.12' + Python313: + PYTHON_VERSION: '3.13' + Python314: + PYTHON_VERSION: '3.14' + steps: + - task: UsePythonVersion@0 + inputs: + versionSpec: $(PYTHON_VERSION) + - powershell: | + $PY_VER = "$(PYTHON_VERSION)" + Write-Host "Python version: $PY_VER" + + # Extract minor version as integers + $versionParts = $PY_VER.Split('.') + $PY_MINOR = [int]$versionParts[1] + Write-Host "Minor version: $PY_MINOR" + Write-Host "##vso[task.setvariable variable=minorVersion;]$PY_MINOR" + + # Set build-related variables based on Python minor version + if( $PY_MINOR -ge 13 ) + { + Write-Host "##vso[task.setvariable variable=proxyWorker;]true" + } + else + { + Write-Host "##vso[task.setvariable variable=proxyWorker;]false" + } + displayName: 'Set necessary variables' + - bash: | + echo "Checking azure_functions_worker (Python < 3.13)..." + cd workers + pip install . invoke + cd tests + python -m invoke -c test_setup build-protos + cd .. + python -c "import pkgutil, importlib; [importlib.import_module(f'azure_functions_worker.{name}') for _, name, _ in pkgutil.walk_packages(['azure_functions_worker'])]" + displayName: 'Python Azure Functions Worker: check for missing dependencies' + condition: eq(variables['proxyWorker'], false) + - bash: | + echo "Checking proxy_worker (Python >= 3.13)..." + cd workers + pip install . invoke + cd tests + python -m invoke -c test_setup build-protos + cd .. + python -c "import pkgutil, importlib; [importlib.import_module(f'proxy_worker.{name}') for _, name, _ in pkgutil.walk_packages(['proxy_worker'])]" + displayName: 'Python Proxy Worker: check for missing dependencies' + condition: eq(variables['proxyWorker'], true) + - bash: | + echo "Checking V1 Library Worker (Python >= 3.13)..." + cd runtimes/v1 + pip install . + python -c "import pkgutil, importlib; [importlib.import_module(f'azure_functions_runtime_v1.{name}') for _, name, _ in pkgutil.walk_packages(['azure_functions_runtime_v1'])]" + displayName: 'Python Library V1: check for missing dependencies' + condition: eq(variables['proxyWorker'], true) + - bash: | + echo "Checking V2 Library Worker (Python >= 3.13)..." + cd runtimes/v2 + pip install . + python -c "import pkgutil, importlib; [importlib.import_module(f'azure_functions_runtime.{name}') for _, name, _ in pkgutil.walk_packages(['azure_functions_runtime'])]" + displayName: 'Python Library V2: check for missing dependencies' + condition: eq(variables['proxyWorker'], true) diff --git a/eng/templates/official/jobs/ci-docker-consumption-tests.yml b/eng/templates/official/jobs/ci-docker-consumption-tests.yml index e5653455b..c4af5c014 100644 --- a/eng/templates/official/jobs/ci-docker-consumption-tests.yml +++ b/eng/templates/official/jobs/ci-docker-consumption-tests.yml @@ -15,30 +15,27 @@ jobs: Python39: PYTHON_VERSION: '3.9' STORAGE_CONNECTION: $(LinuxStorageConnectionString39) - COSMOSDB_CONNECTION: $(LinuxCosmosDBConnectionString39) - EVENTHUB_CONNECTION: $(LinuxEventHubConnectionString39) - SERVICEBUS_CONNECTION: $(LinuxServiceBusConnectionString39) SQL_CONNECTION: $(LinuxSqlConnectionString39) EVENTGRID_URI: $(LinuxEventGridTopicUriString39) EVENTGRID_CONNECTION: $(LinuxEventGridConnectionKeyString39) Python310: PYTHON_VERSION: '3.10' STORAGE_CONNECTION: $(LinuxStorageConnectionString310) - COSMOSDB_CONNECTION: $(LinuxCosmosDBConnectionString310) - EVENTHUB_CONNECTION: $(LinuxEventHubConnectionString310) - SERVICEBUS_CONNECTION: $(LinuxServiceBusConnectionString310) SQL_CONNECTION: $(LinuxSqlConnectionString310) EVENTGRID_URI: $(LinuxEventGridTopicUriString310) EVENTGRID_CONNECTION: $(LinuxEventGridConnectionKeyString310) Python311: PYTHON_VERSION: '3.11' STORAGE_CONNECTION: $(LinuxStorageConnectionString311) - COSMOSDB_CONNECTION: $(LinuxCosmosDBConnectionString311) - EVENTHUB_CONNECTION: $(LinuxEventHubConnectionString311) - SERVICEBUS_CONNECTION: $(LinuxServiceBusConnectionString311) SQL_CONNECTION: $(LinuxSqlConnectionString311) EVENTGRID_URI: $(LinuxEventGridTopicUriString311) EVENTGRID_CONNECTION: $(LinuxEventGridConnectionKeyString311) + Python312: + PYTHON_VERSION: '3.12' + STORAGE_CONNECTION: $(LinuxStorageConnectionString312) + SQL_CONNECTION: $(LinuxSqlConnectionString312) + EVENTGRID_URI: $(LinuxEventGridTopicUriString312) + EVENTGRID_CONNECTION: $(LinuxEventGridConnectionKeyString312) steps: - task: UsePythonVersion@0 @@ -56,9 +53,7 @@ jobs: env: CONSUMPTION_DOCKER_TEST: "true" AzureWebJobsStorage: $(STORAGE_CONNECTION) - AzureWebJobsCosmosDBConnectionString: $(COSMOSDB_CONNECTION) - AzureWebJobsEventHubConnectionString: $(EVENTHUB_CONNECTION) - AzureWebJobsServiceBusConnectionString: $(SERVICEBUS_CONNECTION) + STORAGE_CONNECTION: $(STORAGE_CONNECTION) AzureWebJobsSqlConnectionString: $(SQL_CONNECTION) AzureWebJobsEventGridTopicUri: $(EVENTGRID_URI) AzureWebJobsEventGridConnectionKey: $(EVENTGRID_CONNECTION) diff --git a/eng/templates/official/jobs/ci-docker-dedicated-tests.yml b/eng/templates/official/jobs/ci-docker-dedicated-tests.yml index 728caa42b..dff9f5d1f 100644 --- a/eng/templates/official/jobs/ci-docker-dedicated-tests.yml +++ b/eng/templates/official/jobs/ci-docker-dedicated-tests.yml @@ -15,30 +15,27 @@ jobs: Python39: PYTHON_VERSION: '3.9' STORAGE_CONNECTION: $(LinuxStorageConnectionString39) - COSMOSDB_CONNECTION: $(LinuxCosmosDBConnectionString39) - EVENTHUB_CONNECTION: $(LinuxEventHubConnectionString39) - SERVICEBUS_CONNECTION: $(LinuxServiceBusConnectionString39) SQL_CONNECTION: $(LinuxSqlConnectionString39) EVENTGRID_URI: $(LinuxEventGridTopicUriString39) EVENTGRID_CONNECTION: $(LinuxEventGridConnectionKeyString39) Python310: PYTHON_VERSION: '3.10' STORAGE_CONNECTION: $(LinuxStorageConnectionString310) - COSMOSDB_CONNECTION: $(LinuxCosmosDBConnectionString310) - EVENTHUB_CONNECTION: $(LinuxEventHubConnectionString310) - SERVICEBUS_CONNECTION: $(LinuxServiceBusConnectionString310) SQL_CONNECTION: $(LinuxSqlConnectionString310) EVENTGRID_URI: $(LinuxEventGridTopicUriString310) EVENTGRID_CONNECTION: $(LinuxEventGridConnectionKeyString310) Python311: PYTHON_VERSION: '3.11' STORAGE_CONNECTION: $(LinuxStorageConnectionString311) - COSMOSDB_CONNECTION: $(LinuxCosmosDBConnectionString311) - EVENTHUB_CONNECTION: $(LinuxEventHubConnectionString311) - SERVICEBUS_CONNECTION: $(LinuxServiceBusConnectionString311) SQL_CONNECTION: $(LinuxSqlConnectionString311) EVENTGRID_URI: $(LinuxEventGridTopicUriString311) EVENTGRID_CONNECTION: $(LinuxEventGridConnectionKeyString311) + Python312: + PYTHON_VERSION: '3.12' + STORAGE_CONNECTION: $(LinuxStorageConnectionString312) + SQL_CONNECTION: $(LinuxSqlConnectionString312) + EVENTGRID_URI: $(LinuxEventGridTopicUriString312) + EVENTGRID_CONNECTION: $(LinuxEventGridConnectionKeyString312) steps: - task: UsePythonVersion@0 @@ -56,9 +53,7 @@ jobs: env: DEDICATED_DOCKER_TEST: "true" AzureWebJobsStorage: $(STORAGE_CONNECTION) - AzureWebJobsCosmosDBConnectionString: $(COSMOSDB_CONNECTION) - AzureWebJobsEventHubConnectionString: $(EVENTHUB_CONNECTION) - AzureWebJobsServiceBusConnectionString: $(SERVICEBUS_CONNECTION) + STORAGE_CONNECTION: $(STORAGE_CONNECTION) AzureWebJobsSqlConnectionString: $(SQL_CONNECTION) AzureWebJobsEventGridTopicUri: $(EVENTGRID_URI) AzureWebJobsEventGridConnectionKey: $(EVENTGRID_CONNECTION) diff --git a/eng/templates/official/jobs/publish-release.yml b/eng/templates/official/jobs/publish-release.yml index 54d87313e..2cba69900 100644 --- a/eng/templates/official/jobs/publish-release.yml +++ b/eng/templates/official/jobs/publish-release.yml @@ -123,7 +123,7 @@ jobs: # Modify release_notes.md Write-Host "Adding a new entry in release_notes.md" - Add-Content -Path release_notes.md -Value "`n- Update Python Worker Version to [$newWorkerVersion](https://github.com/Azure/azure-functions-python-worker/releases/tag/$newWorkerVersion)" + Add-Content -Path release_notes.md -Value "- Update Python Worker Version to [$newWorkerVersion](https://github.com/Azure/azure-functions-python-worker/releases/tag/$newWorkerVersion)" # Commit Python Version diff --git a/workers/tests/utils/testutils_docker.py b/workers/tests/utils/testutils_docker.py index feaa186d4..05d3545df 100644 --- a/workers/tests/utils/testutils_docker.py +++ b/workers/tests/utils/testutils_docker.py @@ -68,7 +68,10 @@ class WebHostDockerContainerBase(unittest.TestCase): def find_latest_image(image_repo: str, image_url: str) -> str: - regex = re.compile(_HOST_VERSION + r'.\d+.\d+-python' + _python_version) + # New regex to match version format: 4.1042.100-4-python3.11 + regex = re.compile(_HOST_VERSION + + r'\.10\d+\.\d+(-\d+)?-python' + + _python_version + r'(-appservice)?$') response = requests.get(image_url, allow_redirects=True) if not response.ok: @@ -88,8 +91,16 @@ def find_latest_image(image_repo: str, # sorting all the python versions based on the runtime version and # getting the latest released runtime version for python. - latest_version = sorted(python_versions, key=lambda x: float( - x.split(_HOST_VERSION + '.')[-1].split("-python")[0]))[-1] + # Parse version format: 4.1042.100-4-python3.11 + def parse_version(tag): + # "4.1042.100-4" + version_part = tag.split('-python')[0] + # ["4", "1042", "100", "4"] + parts = version_part.replace('-', '.').split('.') + # (4, 1042, 100, 4) + return tuple(int(p) for p in parts) + + latest_version = sorted(python_versions, key=parse_version)[-1] image_tag = f'{image_repo}:{latest_version}' return image_tag