diff --git a/conda/conda-recipes/azure-mgmt/meta.yaml b/conda/conda-recipes/azure-mgmt/meta.yaml index 6b6a9d67e940..36231c33986f 100644 --- a/conda/conda-recipes/azure-mgmt/meta.yaml +++ b/conda/conda-recipes/azure-mgmt/meta.yaml @@ -64,8 +64,6 @@ test: - azure.mgmt.appcontainers.aio.operations - azure.mgmt.appcontainers.models - azure.mgmt.appcontainers.operations - - azure.mgmt.appplatform - - azure.mgmt.appplatform.aio - azure.mgmt.applicationinsights - azure.mgmt.applicationinsights.aio - azure.mgmt.applicationinsights.v2022_06_15 @@ -73,7 +71,9 @@ test: - azure.mgmt.applicationinsights.v2022_06_15.aio.operations - azure.mgmt.applicationinsights.v2022_06_15.models - azure.mgmt.applicationinsights.v2022_06_15.operations - - azure-mgmt-arizeaiobservabilityeval + - azure.mgmt.appplatform + - azure.mgmt.appplatform.aio + - azure.mgmt.arizeaiobservabilityeval - azure.mgmt.arizeaiobservabilityeval.aio - azure.mgmt.arizeaiobservabilityeval.aio.operations - azure.mgmt.arizeaiobservabilityeval.models @@ -105,6 +105,11 @@ test: - azure.mgmt.automation.aio.operations - azure.mgmt.automation.models - azure.mgmt.automation.operations + - azure.mgmt.avs + - azure.mgmt.avs.aio + - azure.mgmt.avs.aio.operations + - azure.mgmt.avs.models + - azure.mgmt.avs.operations - azure.mgmt.azurearcdata - azure.mgmt.azurearcdata.aio - azure.mgmt.azurearcdata.aio.operations @@ -120,11 +125,6 @@ test: - azure.mgmt.azurestackhci.aio.operations - azure.mgmt.azurestackhci.models - azure.mgmt.azurestackhci.operations - - azure.mgmt.avs - - azure.mgmt.avs.aio - - azure.mgmt.avs.aio.operations - - azure.mgmt.avs.models - - azure.mgmt.avs.operations - azure.mgmt.baremetalinfrastructure - azure.mgmt.baremetalinfrastructure.aio - azure.mgmt.baremetalinfrastructure.aio.operations @@ -150,7 +150,7 @@ test: - azure.mgmt.botservice.aio.operations - azure.mgmt.botservice.models - azure.mgmt.botservice.operations - - azure-mgmt-carbonoptimization + - azure.mgmt.carbonoptimization - azure.mgmt.carbonoptimization.aio - azure.mgmt.carbonoptimization.aio.operations - azure.mgmt.carbonoptimization.models @@ -260,14 +260,8 @@ test: - azure.mgmt.dashboard.operations - azure.mgmt.databox - azure.mgmt.databox.aio - - azure.mgmt.datab - - azure.mgmt.datab.aio - - azure.mgmt.datab.aio.operations - - azure.mgmt.datab.models - - azure.mgmt.datab.operations - azure.mgmt.databoxedge - azure.mgmt.databoxedge.aio - - azure.mgmt.databoxedge.aio - azure.mgmt.databoxedge.aio.operations - azure.mgmt.databoxedge.models - azure.mgmt.databoxedge.operations @@ -276,6 +270,16 @@ test: - azure.mgmt.databoxedge.v2021_02_01_preview.aio.operations - azure.mgmt.databoxedge.v2021_02_01_preview.models - azure.mgmt.databoxedge.v2021_02_01_preview.operations + - azure.mgmt.databricks + - azure.mgmt.databricks.aio + - azure.mgmt.databricks.aio.operations + - azure.mgmt.databricks.models + - azure.mgmt.databricks.operations + - azure.mgmt.datadog + - azure.mgmt.datadog.aio + - azure.mgmt.datadog.aio.operations + - azure.mgmt.datadog.models + - azure.mgmt.datadog.operations - azure.mgmt.datafactory - azure.mgmt.datafactory.aio - azure.mgmt.datafactory.aio.operations @@ -296,16 +300,11 @@ test: - azure.mgmt.datashare.aio.operations - azure.mgmt.datashare.models - azure.mgmt.datashare.operations - - azure.mgmt.databricks - - azure.mgmt.databricks.aio - - azure.mgmt.databricks.aio.operations - - azure.mgmt.databricks.models - - azure.mgmt.databricks.operations - - azure.mgmt.datadog - - azure.mgmt.datadog.aio - - azure.mgmt.datadog.aio.operations - - azure.mgmt.datadog.models - - azure.mgmt.datadog.operations + - azure.mgmt.dellstorage + - azure.mgmt.dellstorage.aio + - azure.mgmt.dellstorage.aio.operations + - azure.mgmt.dellstorage.models + - azure.mgmt.dellstorage.operations - azure.mgmt.deploymentmanager - azure.mgmt.deploymentmanager.aio - azure.mgmt.deploymentmanager.aio.operations @@ -419,7 +418,7 @@ test: - azure.mgmt.hanaonazure.aio.operations - azure.mgmt.hanaonazure.models - azure.mgmt.hanaonazure.operations - - azure-mgmt-hardwaresecuritymodules + - azure.mgmt.hardwaresecuritymodules - azure.mgmt.hardwaresecuritymodules.aio - azure.mgmt.hardwaresecuritymodules.aio.operations - azure.mgmt.hardwaresecuritymodules.models @@ -474,6 +473,11 @@ test: - azure.mgmt.informaticadatamanagement.aio.operations - azure.mgmt.informaticadatamanagement.models - azure.mgmt.informaticadatamanagement.operations + - azure.mgmt.iotfirmwaredefense + - azure.mgmt.iotfirmwaredefense.aio + - azure.mgmt.iotfirmwaredefense.aio.operations + - azure.mgmt.iotfirmwaredefense.models + - azure.mgmt.iotfirmwaredefense.operations - azure.mgmt.iothub - azure.mgmt.iothub.aio - azure.mgmt.iothub.v2023_06_30 @@ -486,11 +490,6 @@ test: - azure.mgmt.iothubprovisioningservices.aio.operations - azure.mgmt.iothubprovisioningservices.models - azure.mgmt.iothubprovisioningservices.operations - - azure.mgmt.iotfirmwaredefense - - azure.mgmt.iotfirmwaredefense.aio - - azure.mgmt.iotfirmwaredefense.aio.operations - - azure.mgmt.iotfirmwaredefense.models - - azure.mgmt.iotfirmwaredefense.operations - azure.mgmt.iotoperations - azure.mgmt.iotoperations.aio - azure.mgmt.iotoperations.aio.operations @@ -515,7 +514,7 @@ test: - azure.mgmt.labservices.aio.operations - azure.mgmt.labservices.models - azure.mgmt.labservices.operations - - azure-mgmt-lambdatesthyperexecute + - azure.mgmt.lambdatesthyperexecute - azure.mgmt.lambdatesthyperexecute.aio - azure.mgmt.lambdatesthyperexecute.aio.operations - azure.mgmt.lambdatesthyperexecute.models @@ -570,16 +569,6 @@ test: - azure.mgmt.managementpartner.aio.operations - azure.mgmt.managementpartner.models - azure.mgmt.managementpartner.operations - - azure.mgmt.managementgroups - - azure.mgmt.managementgroups.aio - - azure.mgmt.managementgroups.aio.operations - - azure.mgmt.managementgroups.models - - azure.mgmt.managementgroups.operations - - azure.mgmt.managementpartner - - azure.mgmt.managementpartner.aio - - azure.mgmt.managementpartner.aio.operations - - azure.mgmt.managementpartner.models - - azure.mgmt.managementpartner.operations - azure.mgmt.maps - azure.mgmt.maps.aio - azure.mgmt.maps.aio.operations @@ -610,7 +599,7 @@ test: - azure.mgmt.mongocluster.aio.operations - azure.mgmt.mongocluster.models - azure.mgmt.mongocluster.operations - - azure-mgmt-mongodbatlas + - azure.mgmt.mongodbatlas - azure.mgmt.mongodbatlas.aio - azure.mgmt.mongodbatlas.aio.operations - azure.mgmt.mongodbatlas.models @@ -645,11 +634,6 @@ test: - azure.mgmt.networkcloud.aio.operations - azure.mgmt.networkcloud.models - azure.mgmt.networkcloud.operations - - azure.mgmt.nginx - - azure.mgmt.nginx.aio - - azure.mgmt.nginx.aio.operations - - azure.mgmt.nginx.models - - azure.mgmt.nginx.operations - azure.mgmt.newrelicobservability - azure.mgmt.newrelicobservability.aio - azure.mgmt.newrelicobservability.aio.operations @@ -680,11 +664,6 @@ test: - azure.mgmt.orbital.aio.operations - azure.mgmt.orbital.models - azure.mgmt.orbital.operations - - azure.mgmt.operationsmanagement - - azure.mgmt.operationsmanagement.aio - - azure.mgmt.operationsmanagement.aio.operations - - azure.mgmt.operationsmanagement.models - - azure.mgmt.operationsmanagement.operations - azure.mgmt.paloaltonetworksngfw - azure.mgmt.paloaltonetworksngfw.aio - azure.mgmt.paloaltonetworksngfw.aio.operations @@ -730,7 +709,7 @@ test: - azure.mgmt.privatedns.aio.operations - azure.mgmt.privatedns.models - azure.mgmt.privatedns.operations - - azure-mgmt-purestorageblock + - azure.mgmt.purestorageblock - azure.mgmt.purestorageblock.aio - azure.mgmt.purestorageblock.aio.operations - azure.mgmt.purestorageblock.models @@ -791,7 +770,7 @@ test: - azure.mgmt.recoveryservicesbackup.passivestamp.aio.operations - azure.mgmt.recoveryservicesbackup.passivestamp.models - azure.mgmt.recoveryservicesbackup.passivestamp.operations - - azure-mgmt-recoveryservicesdatareplication + - azure.mgmt.recoveryservicesdatareplication - azure.mgmt.recoveryservicesdatareplication.aio - azure.mgmt.recoveryservicesdatareplication.aio.operations - azure.mgmt.recoveryservicesdatareplication.models @@ -818,11 +797,6 @@ test: - azure.mgmt.reservations.aio.operations - azure.mgmt.reservations.models - azure.mgmt.reservations.operations - - azure.mgmt.resourcemover - - azure.mgmt.resourcemover.aio - - azure.mgmt.resourcemover.aio.operations - - azure.mgmt.resourcemover.models - - azure.mgmt.resourcemover.operations - azure.mgmt.resource - azure.mgmt.resource.deploymentscripts - azure.mgmt.resource.deploymentscripts.aio @@ -838,11 +812,6 @@ test: - azure.mgmt.resource.features.v2021_07_01.aio.operations - azure.mgmt.resource.features.v2021_07_01.models - azure.mgmt.resource.features.v2021_07_01.operations - - azure.mgmt.resourcegraph - - azure.mgmt.resourcegraph.aio - - azure.mgmt.resourcegraph.aio.operations - - azure.mgmt.resourcegraph.models - - azure.mgmt.resourcegraph.operations - azure.mgmt.resource.links - azure.mgmt.resource.links.aio - azure.mgmt.resource.links.v2016_09_01 @@ -893,6 +862,16 @@ test: - azure.mgmt.resourceconnector.aio.operations - azure.mgmt.resourceconnector.models - azure.mgmt.resourceconnector.operations + - azure.mgmt.resourcegraph + - azure.mgmt.resourcegraph.aio + - azure.mgmt.resourcegraph.aio.operations + - azure.mgmt.resourcegraph.models + - azure.mgmt.resourcegraph.operations + - azure.mgmt.resourcemover + - azure.mgmt.resourcemover.aio + - azure.mgmt.resourcemover.aio.operations + - azure.mgmt.resourcemover.models + - azure.mgmt.resourcemover.operations - azure.mgmt.scvmm - azure.mgmt.scvmm.aio - azure.mgmt.scvmm.aio.operations @@ -924,6 +903,9 @@ test: - azure.mgmt.servermanager - azure.mgmt.servermanager.models - azure.mgmt.servermanager.operations + - azure.mgmt.servicebus + - azure.mgmt.servicebus.aio + - azure.mgmt.servicebus.models - azure.mgmt.servicefabric - azure.mgmt.servicefabric.aio - azure.mgmt.servicefabric.aio.operations @@ -934,9 +916,6 @@ test: - azure.mgmt.servicefabricmanagedclusters.aio.operations - azure.mgmt.servicefabricmanagedclusters.models - azure.mgmt.servicefabricmanagedclusters.operations - - azure.mgmt.servicebus - - azure.mgmt.servicebus.aio - - azure.mgmt.servicebus.models - azure.mgmt.servicelinker - azure.mgmt.servicelinker.aio - azure.mgmt.servicelinker.aio.operations @@ -977,7 +956,7 @@ test: - azure.mgmt.storage.aio.operations - azure.mgmt.storage.models - azure.mgmt.storage.operations - - azure-mgmt-storageactions + - azure.mgmt.storageactions - azure.mgmt.storageactions.aio - azure.mgmt.storageactions.aio.operations - azure.mgmt.storageactions.models diff --git a/conda/conda-recipes/conda_env.yml b/conda/conda-recipes/conda_env.yml index 7b093df90c02..d01bdda64151 100644 --- a/conda/conda-recipes/conda_env.yml +++ b/conda/conda-recipes/conda_env.yml @@ -1,2 +1,2 @@ variables: - AZURESDK_CONDA_VERSION: '2025.12.01' + AZURESDK_CONDA_VERSION: '2026.03.01' diff --git a/conda/conda-releaselogs/azure-ai-agents.md b/conda/conda-releaselogs/azure-ai-agents.md index 05aaf80a500a..affba7f759b7 100644 --- a/conda/conda-releaselogs/azure-ai-agents.md +++ b/conda/conda-releaselogs/azure-ai-agents.md @@ -1,5 +1,11 @@ # Azure AI Agents client library for Python (conda) +## 2026.03.01 + +### Packages included + +- azure-ai-agents-1.1.0 + ## 2025.12.01 ### Packages included diff --git a/conda/conda-releaselogs/azure-ai-contentsafety.md b/conda/conda-releaselogs/azure-ai-contentsafety.md index 4c4ab3e3098c..2fc09c48dd91 100644 --- a/conda/conda-releaselogs/azure-ai-contentsafety.md +++ b/conda/conda-releaselogs/azure-ai-contentsafety.md @@ -1,5 +1,11 @@ # Azure AI Content Safety client library for Python (conda) +## 2026.03.01 + +### Packages included + +- azure-ai-contentsafety-1.0.0 + ## 2025.12.01 ### Packages included diff --git a/conda/conda-releaselogs/azure-ai-documentintelligence.md b/conda/conda-releaselogs/azure-ai-documentintelligence.md index acde2d63e037..8c144f4f0073 100644 --- a/conda/conda-releaselogs/azure-ai-documentintelligence.md +++ b/conda/conda-releaselogs/azure-ai-documentintelligence.md @@ -1,5 +1,11 @@ # Azure AI Document Intelligence client library for Python (conda) +## 2026.03.01 + +### Packages included + +- azure-ai-documentintelligence-1.0.2 + ## 2025.12.01 ### Packages included diff --git a/conda/conda-releaselogs/azure-ai-formrecognizer.md b/conda/conda-releaselogs/azure-ai-formrecognizer.md index a85987b820f0..ba576def3a8e 100644 --- a/conda/conda-releaselogs/azure-ai-formrecognizer.md +++ b/conda/conda-releaselogs/azure-ai-formrecognizer.md @@ -1,5 +1,11 @@ # Azure Form Recognizer client library for Python (conda) +## 2026.03.01 + +### Packages included + +- azure-ai-formrecognizer-3.3.3 + ## 2025.12.01 ### Packages included diff --git a/conda/conda-releaselogs/azure-ai-language-conversations.md b/conda/conda-releaselogs/azure-ai-language-conversations.md index 26712aa410c3..5fba57f5e3b2 100644 --- a/conda/conda-releaselogs/azure-ai-language-conversations.md +++ b/conda/conda-releaselogs/azure-ai-language-conversations.md @@ -1,5 +1,11 @@ # Azure Conversational Language Understanding client library for Python (conda) +## 2026.03.01 + +### Packages included + +- azure-ai-language-conversations-1.1.0 + ## 2025.12.01 ### Packages included diff --git a/conda/conda-releaselogs/azure-ai-language-questionanswering.md b/conda/conda-releaselogs/azure-ai-language-questionanswering.md index f2bf5e2c9dbe..8b581fdf89a1 100644 --- a/conda/conda-releaselogs/azure-ai-language-questionanswering.md +++ b/conda/conda-releaselogs/azure-ai-language-questionanswering.md @@ -1,5 +1,11 @@ # Azure Cognitive Language Services Question Answering client library for Python (conda) +## 2026.03.01 + +### Packages included + +- azure-ai-language-questionanswering-1.1.0 + ## 2025.12.01 ### Packages included diff --git a/conda/conda-releaselogs/azure-ai-ml.md b/conda/conda-releaselogs/azure-ai-ml.md index 75aebd99a7b3..a9e303c3ea7c 100644 --- a/conda/conda-releaselogs/azure-ai-ml.md +++ b/conda/conda-releaselogs/azure-ai-ml.md @@ -1,5 +1,11 @@ # Azure ML Package client library for Python (conda) +## 2026.03.01 + +### Packages included + +- azure-ai-ml-1.31.0 + ## 2025.12.01 ### Packages included diff --git a/conda/conda-releaselogs/azure-ai-projects.md b/conda/conda-releaselogs/azure-ai-projects.md index 23d7430d104a..59b4b095b67f 100644 --- a/conda/conda-releaselogs/azure-ai-projects.md +++ b/conda/conda-releaselogs/azure-ai-projects.md @@ -1,5 +1,11 @@ # Azure AI Projects client library for Python (conda) +## 2026.03.01 + +### Packages included + +- azure-ai-projects-1.0.0 + ## 2025.12.01 ### Packages included diff --git a/conda/conda-releaselogs/azure-ai-textanalytics.md b/conda/conda-releaselogs/azure-ai-textanalytics.md index 3e3ad9d115f2..ba928e5c5b04 100644 --- a/conda/conda-releaselogs/azure-ai-textanalytics.md +++ b/conda/conda-releaselogs/azure-ai-textanalytics.md @@ -1,5 +1,11 @@ # Azure Text Analytics client library for Python (conda) +## 2026.03.01 + +### Packages included + +- azure-ai-textanalytics-5.3.0 + ## 2025.12.01 ### Packages included diff --git a/conda/conda-releaselogs/azure-ai-translation-document.md b/conda/conda-releaselogs/azure-ai-translation-document.md index 9ac9766461f4..41f1acbf06d9 100644 --- a/conda/conda-releaselogs/azure-ai-translation-document.md +++ b/conda/conda-releaselogs/azure-ai-translation-document.md @@ -1,5 +1,11 @@ # Azure Document Translation client library for Python (conda) +## 2026.03.01 + +### Packages included + +- azure-ai-translation-document-1.1.0 + ## 2025.12.01 ### Packages included diff --git a/conda/conda-releaselogs/azure-ai-translation-text.md b/conda/conda-releaselogs/azure-ai-translation-text.md index e7d12dbdf681..9fc6d72bd2ab 100644 --- a/conda/conda-releaselogs/azure-ai-translation-text.md +++ b/conda/conda-releaselogs/azure-ai-translation-text.md @@ -1,5 +1,11 @@ # Azure Text Translation client library for Python (conda) +## 2026.03.01 + +### Packages included + +- azure-ai-translation-text-1.0.1 + ## 2025.12.01 ### Packages included diff --git a/conda/conda-releaselogs/azure-ai-vision.md b/conda/conda-releaselogs/azure-ai-vision.md index 13f277140dfd..56d27efefa3f 100644 --- a/conda/conda-releaselogs/azure-ai-vision.md +++ b/conda/conda-releaselogs/azure-ai-vision.md @@ -1,5 +1,11 @@ # Azure AI Vision client library for Python (conda) +## 2026.03.01 + +### Packages included + +- azure-ai-vision-imageanalysis-1.0.0 + ## 2025.12.01 ### Packages included diff --git a/conda/conda-releaselogs/azure-ai-voicelive.md b/conda/conda-releaselogs/azure-ai-voicelive.md index db3ca93064b5..79bcc7e0735d 100644 --- a/conda/conda-releaselogs/azure-ai-voicelive.md +++ b/conda/conda-releaselogs/azure-ai-voicelive.md @@ -1,5 +1,11 @@ # Azure AI VoiceLive client library for Python (conda) +## 2026.03.01 + +### Packages included + +- azure-ai-voicelive-1.1.0 + ## 2025.12.01 ### Packages included diff --git a/conda/conda-releaselogs/azure-appconfiguration.md b/conda/conda-releaselogs/azure-appconfiguration.md index 5129d6fcd864..58963a558567 100644 --- a/conda/conda-releaselogs/azure-appconfiguration.md +++ b/conda/conda-releaselogs/azure-appconfiguration.md @@ -1,5 +1,11 @@ # Azure App Configuration client library for Python (conda) +## 2026.03.01 + +### Packages included + +- azure-appconfiguration-1.8.0 + ## 2025.12.01 ### Packages included diff --git a/conda/conda-releaselogs/azure-communication.md b/conda/conda-releaselogs/azure-communication.md index 3a12f9ba049c..4b4a2ef53fb3 100644 --- a/conda/conda-releaselogs/azure-communication.md +++ b/conda/conda-releaselogs/azure-communication.md @@ -1,5 +1,19 @@ # Azure Communication client library for Python (conda) +## 2026.03.01 + +### Packages included + +- azure-communication-callautomation-1.5.0 +- azure-communication-chat-1.3.0 +- azure-communication-email-1.1.0 +- azure-communication-identity-1.5.0 +- azure-communication-jobrouter-1.0.0 +- azure-communication-messages-1.1.0 +- azure-communication-phonenumbers-1.4.0 +- azure-communication-rooms-1.2.0 +- azure-communication-sms-1.1.0 + ## 2025.12.01 ### Packages included diff --git a/conda/conda-releaselogs/azure-confidentialledger.md b/conda/conda-releaselogs/azure-confidentialledger.md index 7457cecdb54f..3d0a8918eec2 100644 --- a/conda/conda-releaselogs/azure-confidentialledger.md +++ b/conda/conda-releaselogs/azure-confidentialledger.md @@ -1,5 +1,11 @@ # Microsoft Azure Confidential Ledger Client Library for Python (conda) +## 2026.03.01 + +### Packages included + +- azure-confidentialledger-1.1.1 + ## 2025.12.01 ### Packages included diff --git a/conda/conda-releaselogs/azure-containerregistry.md b/conda/conda-releaselogs/azure-containerregistry.md index 2a42aac07ace..95042ede7684 100644 --- a/conda/conda-releaselogs/azure-containerregistry.md +++ b/conda/conda-releaselogs/azure-containerregistry.md @@ -1,5 +1,11 @@ # Azure Container Registry client library for Python (conda) +## 2026.03.01 + +### Packages included + +- azure-containerregistry-1.2.0 + ## 2025.12.01 ### Packages included diff --git a/conda/conda-releaselogs/azure-core.md b/conda/conda-releaselogs/azure-core.md index db3bc061d626..a4e412e41d5f 100644 --- a/conda/conda-releaselogs/azure-core.md +++ b/conda/conda-releaselogs/azure-core.md @@ -1,5 +1,12 @@ # Azure Core client library for Python (conda) +## 2026.03.01 + +### Packages included + +- azure-core-1.38.0 +- azure-mgmt-core-1.6.0 + ## 2025.12.01 ### Packages included diff --git a/conda/conda-releaselogs/azure-cosmos.md b/conda/conda-releaselogs/azure-cosmos.md index 9ac4d86dcad5..5f3f88a8f5ca 100644 --- a/conda/conda-releaselogs/azure-cosmos.md +++ b/conda/conda-releaselogs/azure-cosmos.md @@ -1,5 +1,11 @@ # Azure Cosmos DB SQL API client library for Python (conda) +## 2026.03.01 + +### Packages included + +- azure-cosmos-4.14.5 + ## 2025.12.01 ### Packages included diff --git a/conda/conda-releaselogs/azure-data-tables.md b/conda/conda-releaselogs/azure-data-tables.md index 63c06ae06f6f..d53b7e8fdc49 100644 --- a/conda/conda-releaselogs/azure-data-tables.md +++ b/conda/conda-releaselogs/azure-data-tables.md @@ -1,5 +1,11 @@ # Azure Tables client library for Python (conda) +## 2026.03.01 + +### Packages included + +- azure-data-tables-12.7.0 + ## 2025.12.01 ### Packages included diff --git a/conda/conda-releaselogs/azure-developer-loadtesting.md b/conda/conda-releaselogs/azure-developer-loadtesting.md index dfd8f637a467..eb5864dc6d95 100644 --- a/conda/conda-releaselogs/azure-developer-loadtesting.md +++ b/conda/conda-releaselogs/azure-developer-loadtesting.md @@ -1,5 +1,11 @@ # Microsoft Azure Developer LoadTesting Client Library for Python (conda) +## 2026.03.01 + +### Packages included + +- azure-developer-loadtesting-1.0.1 + ## 2025.12.01 ### Packages included diff --git a/conda/conda-releaselogs/azure-digitaltwins-core.md b/conda/conda-releaselogs/azure-digitaltwins-core.md index e43e293a0565..4f61687a8f2d 100644 --- a/conda/conda-releaselogs/azure-digitaltwins-core.md +++ b/conda/conda-releaselogs/azure-digitaltwins-core.md @@ -1,5 +1,11 @@ # Azure Digital Twins Core client library for Python (conda) +## 2026.03.01 + +### Packages included + +- azure-digitaltwins-core-1.3.0 + ## 2025.12.01 ### Packages included diff --git a/conda/conda-releaselogs/azure-eventgrid.md b/conda/conda-releaselogs/azure-eventgrid.md index 44e5356d233d..83cc0c3f38a0 100644 --- a/conda/conda-releaselogs/azure-eventgrid.md +++ b/conda/conda-releaselogs/azure-eventgrid.md @@ -1,5 +1,11 @@ # Azure Event Grid client library for Python (conda) +## 2026.03.01 + +### Packages included + +- azure-eventgrid-4.22.0 + ## 2025.12.01 ### Packages included diff --git a/conda/conda-releaselogs/azure-eventhub.md b/conda/conda-releaselogs/azure-eventhub.md index 403b091a470d..ca06e0ff6726 100644 --- a/conda/conda-releaselogs/azure-eventhub.md +++ b/conda/conda-releaselogs/azure-eventhub.md @@ -1,5 +1,13 @@ # Azure Event Hubs client library for Python (conda) +## 2026.03.01 + +### Packages included + +- azure-eventhub-checkpointstoreblob-1.2.0 +- azure-eventhub-checkpointstoreblob-aio-1.2.0 +- azure-eventhub-5.15.1 + ## 2025.12.01 ### Packages included diff --git a/conda/conda-releaselogs/azure-health-deidentification.md b/conda/conda-releaselogs/azure-health-deidentification.md index 470ac6d4dbd1..2ab7c885db8e 100644 --- a/conda/conda-releaselogs/azure-health-deidentification.md +++ b/conda/conda-releaselogs/azure-health-deidentification.md @@ -1,5 +1,11 @@ # Azure Health Deidentification client library for Python (conda) +## 2026.03.01 + +### Packages included + +- azure-health-deidentification-1.0.0 + ## 2025.12.01 ### Packages included diff --git a/conda/conda-releaselogs/azure-healthinsights.md b/conda/conda-releaselogs/azure-healthinsights.md index b5102618e064..ee4821edfa63 100644 --- a/conda/conda-releaselogs/azure-healthinsights.md +++ b/conda/conda-releaselogs/azure-healthinsights.md @@ -1,5 +1,11 @@ # Azure Cognitive Services Health Insights client library for Python (conda) +## 2026.03.01 + +### Packages included + +- azure-healthinsights-radiologyinsights-1.1.0 + ## 2025.12.01 ### Packages included diff --git a/conda/conda-releaselogs/azure-identity.md b/conda/conda-releaselogs/azure-identity.md index c72eabfe04fd..d9e1def28b89 100644 --- a/conda/conda-releaselogs/azure-identity.md +++ b/conda/conda-releaselogs/azure-identity.md @@ -1,5 +1,11 @@ # Azure Identity client library for Python (conda) +## 2026.03.01 + +### Packages included + +- azure-identity-1.25.1 + ## 2025.12.01 ### Packages included diff --git a/conda/conda-releaselogs/azure-iot-deviceupdate.md b/conda/conda-releaselogs/azure-iot-deviceupdate.md index e949969d8fac..33a508f1c050 100644 --- a/conda/conda-releaselogs/azure-iot-deviceupdate.md +++ b/conda/conda-releaselogs/azure-iot-deviceupdate.md @@ -1,5 +1,11 @@ # Azure Device Update for IoT Hub client library for Python (conda) +## 2026.03.01 + +### Packages included + +- azure-iot-deviceupdate-1.0.0 + ## 2025.12.01 ### Packages included diff --git a/conda/conda-releaselogs/azure-keyvault.md b/conda/conda-releaselogs/azure-keyvault.md index 706a27680bdb..b08857b127ab 100644 --- a/conda/conda-releaselogs/azure-keyvault.md +++ b/conda/conda-releaselogs/azure-keyvault.md @@ -1,5 +1,14 @@ # Azure Key Vault client library for Python (conda) +## 2026.03.01 + +### Packages included + +- azure-keyvault-administration-4.6.0 +- azure-keyvault-certificates-4.10.0 +- azure-keyvault-keys-4.11.0 +- azure-keyvault-secrets-4.10.0 + ## 2025.12.01 ### Packages included diff --git a/conda/conda-releaselogs/azure-messaging-webpubsubclient.md b/conda/conda-releaselogs/azure-messaging-webpubsubclient.md index 0c9e886af706..6410c5081379 100644 --- a/conda/conda-releaselogs/azure-messaging-webpubsubclient.md +++ b/conda/conda-releaselogs/azure-messaging-webpubsubclient.md @@ -1,5 +1,11 @@ # Azure Web PubSub client library for Python (conda) +## 2026.03.01 + +### Packages included + +- azure-messaging-webpubsubclient-1.1.0 + ## 2025.12.01 ### Packages included diff --git a/conda/conda-releaselogs/azure-messaging-webpubsubservice.md b/conda/conda-releaselogs/azure-messaging-webpubsubservice.md index dccd483bb026..9f3d7df99a13 100644 --- a/conda/conda-releaselogs/azure-messaging-webpubsubservice.md +++ b/conda/conda-releaselogs/azure-messaging-webpubsubservice.md @@ -1,5 +1,11 @@ # Azure Web PubSub service client library for Python (conda) +## 2026.03.01 + +### Packages included + +- azure-messaging-webpubsubservice-1.3.0 + ## 2025.12.01 ### Packages included diff --git a/conda/conda-releaselogs/azure-mgmt.md b/conda/conda-releaselogs/azure-mgmt.md index 0da51cb68d27..39f0568bc0ca 100644 --- a/conda/conda-releaselogs/azure-mgmt.md +++ b/conda/conda-releaselogs/azure-mgmt.md @@ -1,5 +1,196 @@ # Azure Resource Management library for Python (conda) +## 2026.03.01 + +### Packages included + +- azure-mgmt-core-1.6.0 +- azure-mgmt-devcenter-1.1.0 +- azure-mgmt-elasticsan-1.1.0 +- azure-mgmt-advisor-9.0.0 +- azure-mgmt-alertsmanagement-1.0.0 +- azure-mgmt-apicenter-1.0.0 +- azure-mgmt-apimanagement-5.0.0 +- azure-mgmt-appcomplianceautomation-1.0.0 +- azure-mgmt-appconfiguration-5.0.0 +- azure-mgmt-web-10.1.0 +- azure-mgmt-applicationinsights-4.1.0 +- azure-mgmt-azurearcdata-1.0.0 +- azure-mgmt-arizeaiobservabilityeval-1.0.0 +- azure-mgmt-attestation-1.0.0 +- azure-mgmt-authorization-4.0.0 +- azure-mgmt-automanage-1.0.0 +- azure-mgmt-automation-1.0.0 +- azure-mgmt-search-9.2.0 +- azure-mgmt-azurestack-1.0.0 +- azure-mgmt-azurestackhci-7.0.0 +- azure-mgmt-avs-10.0.0 +- azure-mgmt-baremetalinfrastructure-1.0.0 +- azure-mgmt-batch-18.0.0 +- azure-mgmt-billing-7.0.0 +- azure-mgmt-botservice-2.0.0 +- azure-mgmt-carbonoptimization-1.0.0 +- azure-mgmt-changeanalysis-1.0.0 +- azure-mgmt-chaos-2.0.0 +- azure-mgmt-cognitiveservices-14.1.0 +- azure-mgmt-commerce-6.0.0 +- azure-mgmt-communication-2.2.0 +- azure-mgmt-compute-37.2.0 +- azure-mgmt-computefleet-1.0.0 +- azure-mgmt-computeschedule-1.1.0 +- azure-mgmt-confidentialledger-1.0.0 +- azure-mgmt-confluent-2.1.0 +- azure-mgmt-connectedvmware-1.0.0 +- azure-mgmt-consumption-10.0.0 +- azure-mgmt-appcontainers-4.0.0 +- azure-mgmt-containerinstance-10.1.0 +- azure-mgmt-containerregistry-14.0.0 +- azure-mgmt-containerservice-40.2.0 +- azure-mgmt-containerservicefleet-3.1.0 +- azure-mgmt-cdn-13.1.1 +- azure-mgmt-cosmosdb-9.9.0 +- azure-mgmt-cosmosdbforpostgresql-1.0.0 +- azure-mgmt-costmanagement-4.0.1 +- azure-mgmt-customproviders-1.0.0 +- azure-mgmt-databox-3.1.0 +- azure-mgmt-databoxedge-2.0.0 +- azure-mgmt-datafactory-9.2.0 +- azure-mgmt-datalake-store-1.0.0 +- azure-mgmt-datamigration-10.1.0 +- azure-mgmt-dataprotection-2.0.1 +- azure-mgmt-datashare-1.0.0 +- azure-mgmt-databricks-2.0.0 +- azure-mgmt-datadog-2.1.0 +- azure-mgmt-dellstorage-1.0.0 +- azure-mgmt-deploymentmanager-1.0.0 +- azure-mgmt-desktopvirtualization-2.0.0 +- azure-mgmt-iothubprovisioningservices-1.1.0 +- azure-mgmt-deviceregistry-1.1.0 +- azure-mgmt-deviceupdate-1.1.0 +- azure-mgmt-devopsinfrastructure-1.0.0 +- azure-mgmt-devtestlabs-9.0.0 +- azure-mgmt-digitaltwins-7.0.0 +- azure-mgmt-dns-9.0.0 +- azure-mgmt-dnsresolver-1.1.0 +- azure-mgmt-durabletask-1.0.0 +- azure-mgmt-dynatrace-2.0.0 +- azure-mgmt-edgeorder-2.0.0 +- azure-mgmt-elastic-2.0.0 +- azure-mgmt-eventgrid-10.4.0 +- azure-mgmt-eventhub-11.2.0 +- azure-mgmt-extendedlocation-2.0.0 +- azure-mgmt-fabric-1.0.0 +- azure-mgmt-fluidrelay-1.0.0 +- azure-mgmt-frontdoor-1.2.0 +- azure-mgmt-graphservices-1.0.0 +- azure-mgmt-hanaonazure-1.0.0 +- azure-mgmt-hardwaresecuritymodules-1.0.0 +- azure-mgmt-hdinsight-9.0.0 +- azure-mgmt-healthdataaiservices-1.0.0 +- azure-mgmt-healthcareapis-2.1.0 +- azure-mgmt-hybridcompute-9.0.0 +- azure-mgmt-hybridconnectivity-1.0.0 +- azure-mgmt-hybridcontainerservice-1.0.0 +- azure-mgmt-hybridkubernetes-1.1.0 +- azure-mgmt-hybridnetwork-2.0.0 +- azure-mgmt-imagebuilder-1.4.0 +- azure-mgmt-informaticadatamanagement-1.0.0 +- azure-mgmt-iotcentral-9.0.0 +- azure-mgmt-iotfirmwaredefense-2.0.0 +- azure-mgmt-iothub-4.0.0 +- azure-mgmt-iotoperations-1.0.0 +- azure-mgmt-keyvault-13.0.0 +- azure-mgmt-kubernetesconfiguration-3.1.0 +- azure-mgmt-kusto-3.4.0 +- azure-mgmt-labservices-2.0.0 +- azure-mgmt-lambdatesthyperexecute-1.0.0 +- azure-mgmt-loadtesting-1.0.0 +- azure-mgmt-loganalytics-13.1.1 +- azure-mgmt-logic-10.0.0 +- azure-mgmt-machinelearningservices-1.0.0 +- azure-mgmt-maintenance-2.1.0 +- azure-mgmt-dashboard-2.0.0 +- azure-mgmt-managednetworkfabric-1.0.0 +- azure-mgmt-msi-7.1.0 +- azure-mgmt-managedservices-6.0.0 +- azure-mgmt-managementgroups-1.0.0 +- azure-mgmt-managementpartner-1.0.0 +- azure-mgmt-maps-2.1.0 +- azure-mgmt-marketplaceordering-1.1.0 +- azure-mgmt-mixedreality-1.0.0 +- azure-mgmt-mongocluster-1.1.0 +- azure-mgmt-mongodbatlas-1.0.0 +- azure-mgmt-monitor-7.0.0 +- azure-mgmt-mysqlflexibleservers-1.0.0 +- azure-mgmt-neonpostgres-1.0.0 +- azure-mgmt-netapp-14.0.1 +- azure-mgmt-network-30.1.0 +- azure-mgmt-networkcloud-2.2.0 +- azure-mgmt-newrelicobservability-1.1.0 +- azure-mgmt-nginx-3.0.0 +- azure-mgmt-notificationhubs-8.0.0 +- azure-mgmt-operationsmanagement-1.0.0 +- azure-mgmt-oracledatabase-3.0.0 +- azure-mgmt-orbital-2.0.0 +- azure-mgmt-paloaltonetworksngfw-1.1.0 +- azure-mgmt-peering-1.0.0 +- azure-mgmt-playwright-1.0.0 +- azure-mgmt-policyinsights-1.0.0 +- azure-mgmt-portal-1.0.0 +- azure-mgmt-rdbms-10.1.1 +- azure-mgmt-postgresqlflexibleservers-2.0.0 +- azure-mgmt-powerbidedicated-1.0.0 +- azure-mgmt-privatedns-1.2.0 +- azure-mgmt-purestorageblock-1.0.0 +- azure-mgmt-purview-1.0.0 +- azure-mgmt-qumulo-2.0.0 +- azure-mgmt-quota-3.0.1 +- azure-mgmt-recoveryservices-4.0.0 +- azure-mgmt-recoveryservicesbackup-10.0.0 +- azure-mgmt-recoveryservicesdatareplication-1.0.0 +- azure-mgmt-recoveryservicessiterecovery-1.3.0 +- azure-mgmt-redhatopenshift-2.0.0 +- azure-mgmt-redis-14.5.0 +- azure-mgmt-redisenterprise-3.1.0 +- azure-mgmt-relay-1.1.0 +- azure-mgmt-reservations-2.3.0 +- azure-mgmt-resourceconnector-1.0.0 +- azure-mgmt-resourcegraph-8.0.1 +- azure-mgmt-resourcemover-1.1.0 +- azure-mgmt-resource-24.0.0 +- azure-mgmt-scvmm-1.0.0 +- azure-mgmt-security-7.0.0 +- azure-mgmt-securityinsight-1.0.0 +- azure-mgmt-selfhelp-1.0.0 +- azure-mgmt-serialconsole-1.0.0 +- azure-mgmt-servicebus-9.0.0 +- azure-mgmt-servicefabric-2.1.0 +- azure-mgmt-servicefabricmanagedclusters-2.0.0 +- azure-mgmt-servicelinker-1.1.0 +- azure-mgmt-servicenetworking-2.0.0 +- azure-mgmt-signalr-1.2.0 +- azure-mgmt-sitemanager-1.0.1 +- azure-mgmt-sphere-1.0.0 +- azure-mgmt-sql-3.0.1 +- azure-mgmt-standbypool-2.0.0 +- azure-mgmt-storage-24.0.0 +- azure-mgmt-storageactions-1.0.0 +- azure-mgmt-storagecache-3.0.1 +- azure-mgmt-storagemover-3.0.0 +- azure-mgmt-storagepool-1.0.0 +- azure-mgmt-storagesync-1.0.0 +- azure-mgmt-storagediscovery-1.0.1 +- azure-mgmt-streamanalytics-1.0.0 +- azure-mgmt-subscription-3.1.1 +- azure-mgmt-support-7.0.0 +- azure-mgmt-synapse-2.0.0 +- azure-mgmt-timeseriesinsights-1.0.0 +- azure-mgmt-trafficmanager-1.1.0 +- azure-mgmt-voiceservices-1.0.0 +- azure-mgmt-webpubsub-2.0.0 +- azure-mgmt-workloads-1.0.0 +- azure-mgmt-workloadssapvirtualinstance-1.0.0 + ## 2025.12.01 ### Packages included diff --git a/conda/conda-releaselogs/azure-monitor-ingestion.md b/conda/conda-releaselogs/azure-monitor-ingestion.md index 49f4d6b2fb07..0735796b4226 100644 --- a/conda/conda-releaselogs/azure-monitor-ingestion.md +++ b/conda/conda-releaselogs/azure-monitor-ingestion.md @@ -1,5 +1,11 @@ # Azure Monitor Ingestion client library for Python (conda) +## 2026.03.01 + +### Packages included + +- azure-monitor-ingestion-1.1.0 + ## 2025.12.01 ### Packages included diff --git a/conda/conda-releaselogs/azure-monitor-opentelemetry.md b/conda/conda-releaselogs/azure-monitor-opentelemetry.md index 119b14a0daf8..d9e865576c52 100644 --- a/conda/conda-releaselogs/azure-monitor-opentelemetry.md +++ b/conda/conda-releaselogs/azure-monitor-opentelemetry.md @@ -4,4 +4,4 @@ ### Packages included -- azure-monitor-opentelemetry-1.8.4 +- azure-monitor-opentelemetry-1.8.5 diff --git a/conda/conda-releaselogs/azure-monitor-query.md b/conda/conda-releaselogs/azure-monitor-query.md index bf66a56cb527..a1e1efdadccd 100644 --- a/conda/conda-releaselogs/azure-monitor-query.md +++ b/conda/conda-releaselogs/azure-monitor-query.md @@ -1,5 +1,11 @@ # Azure Monitor Query client library for Python (conda) +## 2026.03.01 + +### Packages included + +- azure-monitor-query-2.0.0 + ## 2025.12.01 ### Packages included diff --git a/conda/conda-releaselogs/azure-monitor-querymetrics.md b/conda/conda-releaselogs/azure-monitor-querymetrics.md index cf7cba4dd819..9787f3a22235 100644 --- a/conda/conda-releaselogs/azure-monitor-querymetrics.md +++ b/conda/conda-releaselogs/azure-monitor-querymetrics.md @@ -1,5 +1,11 @@ # Azure Monitor Query Metrics client library for Python (conda) +## 2026.03.01 + +### Packages included + +- azure-monitor-querymetrics-1.0.0 + ## 2025.12.01 ### Packages included diff --git a/conda/conda-releaselogs/azure-schemaregistry.md b/conda/conda-releaselogs/azure-schemaregistry.md index a46845ae5a10..1fd07fd734eb 100644 --- a/conda/conda-releaselogs/azure-schemaregistry.md +++ b/conda/conda-releaselogs/azure-schemaregistry.md @@ -1,5 +1,12 @@ # Azure Schema Registry client library for Python (conda) +## 2026.03.01 + +### Packages included + +- azure-schemaregistry-1.3.0 +- azure-schemaregistry-avroencoder-1.0.0 + ## 2025.12.01 ### Packages included diff --git a/conda/conda-releaselogs/azure-search-documents.md b/conda/conda-releaselogs/azure-search-documents.md index a5307ea49733..c44ea5dfb002 100644 --- a/conda/conda-releaselogs/azure-search-documents.md +++ b/conda/conda-releaselogs/azure-search-documents.md @@ -1,5 +1,11 @@ # Azure Cognitive Search client library for Python (conda) +## 2026.03.01 + +### Packages included + +- azure-search-documents-11.6.0 + ## 2025.12.01 ### Packages included diff --git a/conda/conda-releaselogs/azure-security-attestation.md b/conda/conda-releaselogs/azure-security-attestation.md index 77c2811e0c5d..c2642fff0074 100644 --- a/conda/conda-releaselogs/azure-security-attestation.md +++ b/conda/conda-releaselogs/azure-security-attestation.md @@ -1,5 +1,11 @@ # Azure Attestation client library for Python (conda) +## 2026.03.01 + +### Packages included + +- azure-security-attestation-1.0.0 + ## 2025.12.01 ### Packages included diff --git a/conda/conda-releaselogs/azure-servicebus.md b/conda/conda-releaselogs/azure-servicebus.md index e7b522072f9a..bbc8c7c1625e 100644 --- a/conda/conda-releaselogs/azure-servicebus.md +++ b/conda/conda-releaselogs/azure-servicebus.md @@ -1,5 +1,11 @@ # Azure Service Bus client library for Python (conda) +## 2026.03.01 + +### Packages included + +- azure-servicebus-7.14.3 + ## 2025.12.01 ### Packages included diff --git a/conda/conda-releaselogs/azure-storage.md b/conda/conda-releaselogs/azure-storage.md index f7a15a83b7e6..24dd7144ed00 100644 --- a/conda/conda-releaselogs/azure-storage.md +++ b/conda/conda-releaselogs/azure-storage.md @@ -1,5 +1,14 @@ # Azure Storage client library for Python (conda) +## 2026.03.01 + +### Packages included + +- azure-storage-blob-12.28.0 +- azure-storage-file-datalake-12.23.0 +- azure-storage-file-share-12.24.0 +- azure-storage-queue-12.15.0 + ## 2025.12.01 ### Packages included diff --git a/conda/conda-releaselogs/msal-extensions.md b/conda/conda-releaselogs/msal-extensions.md index 4ed90bb480de..dd54d58f8365 100644 --- a/conda/conda-releaselogs/msal-extensions.md +++ b/conda/conda-releaselogs/msal-extensions.md @@ -1,5 +1,11 @@ # Microsoft Authentication Extensions for Python (conda) +## 2026.03.01 + +### Packages included + +- msal-extensions-1.3.1 + ## 2025.12.01 ### Packages included diff --git a/conda/conda-releaselogs/msal.md b/conda/conda-releaselogs/msal.md index 165efccf1226..41c96788fc55 100644 --- a/conda/conda-releaselogs/msal.md +++ b/conda/conda-releaselogs/msal.md @@ -1,5 +1,11 @@ # Microsoft Authentication Library (MSAL) for Python (conda) +## 2026.03.01 + +### Packages included + +- msal-1.34.0 + ## 2025.12.01 ### Packages included diff --git a/conda/conda_helper_functions.py b/conda/conda_helper_functions.py new file mode 100644 index 000000000000..4d950a88bd8e --- /dev/null +++ b/conda/conda_helper_functions.py @@ -0,0 +1,262 @@ +""" +Helper functions for updating conda files. +""" + +import os +import glob +from typing import Dict, List, Optional, Tuple +import csv +import json +from ci_tools.logging import logger +import urllib.request +from datetime import datetime +from ci_tools.parsing import ParsedSetup + +ROOT_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) +SDK_DIR = os.path.join(ROOT_DIR, "sdk") + +AZURE_SDK_CSV_URL = "https://raw.githubusercontent.com/Azure/azure-sdk/main/_data/releases/latest/python-packages.csv" +PACKAGE_COL = "Package" +LATEST_GA_DATE_COL = "LatestGADate" +VERSION_GA_COL = "VersionGA" +FIRST_GA_DATE_COL = "FirstGADate" +DISPLAY_NAME_COL = "DisplayName" +SERVICE_NAME_COL = "ServiceName" +REPO_PATH_COL = "RepoPath" +TYPE_COL = "Type" +SUPPORT_COL = "Support" + +# ===================================== +# Helpers for handling bundled releases +# ===================================== + + +def get_package_path(package_name: str) -> Optional[str]: + """Get the filesystem path of an SDK package given its name.""" + pattern = os.path.join(SDK_DIR, "**", package_name) + matches = glob.glob(pattern, recursive=True) + if not matches: + logger.error(f"Package path not found for package: {package_name}") + return None + return matches[0] + + +def get_bundle_name(package_name: str) -> Optional[str]: + """ + Check bundled release config from package's pyproject.toml file given the package name. + + If bundled, return the bundle name; otherwise, return None. + """ + package_path = get_package_path(package_name) + if not package_path: + logger.warning(f"Cannot determine package path for {package_name}") + return None + parsed = ParsedSetup.from_path(package_path) + if not parsed: + # can't proceed, need to know if it's bundled or not + logger.error(f"Failed to parse setup for package {package_name}") + raise Exception(f"Failed to parse setup for package {package_name}") + + conda_config = parsed.get_conda_config() + + if not conda_config: + if parsed.is_stable_release(): + raise Exception( + f"Stable release package {package_name} needs a conda config" + ) + + # beta or alpha package are not released + logger.warning( + f"No conda config found for package {package_name}, which may be a pre-release" + ) + return None + + if conda_config and "bundle_name" in conda_config: + return conda_config["bundle_name"] + + return None + + +def map_bundle_to_packages(package_names: List[str]) -> Dict[str, List[str]]: + """Create a mapping of bundle names to their constituent package names.""" + logger.info("Mapping bundle names to packages...") + all_paths = glob.glob(os.path.join(SDK_DIR, "*", "*")) + # Exclude temp directories like .tox, .venv, __pycache__, etc. + path_lookup = { + os.path.basename(p): p + for p in all_paths + if os.path.isdir(p) and not os.path.basename(p).startswith((".", "__")) + } + + bundle_map = {} + for package_name in package_names: + logger.debug(f"Processing package for bundle mapping: {package_name}") + package_path = path_lookup.get(package_name) + if not package_path: + logger.warning(f"Package path not found for {package_name}") + continue + + # Skip directories without pyproject.toml + if not os.path.exists(os.path.join(package_path, "pyproject.toml")): + logger.warning(f"Skipping {package_name}: no pyproject.toml found") + continue + + parsed = ParsedSetup.from_path(package_path) + if not parsed: + logger.error(f"Failed to parse setup for package {package_name}") + continue + + conda_config = parsed.get_conda_config() + if conda_config and "bundle_name" in conda_config: + bundle_name = conda_config["bundle_name"] + logger.debug(f"Bundle name for package {package_name}: {bundle_name}") + bundle_map.setdefault(bundle_name, []).append(package_name) + + return bundle_map + + +# ===================================== +# Utility functions for parsing data +# ===================================== + + +def parse_csv() -> List[Dict[str, str]]: + """Download and parse the Azure SDK Python packages CSV file.""" + try: + logger.info(f"Downloading CSV from {AZURE_SDK_CSV_URL}") + + with urllib.request.urlopen(AZURE_SDK_CSV_URL) as response: + csv_content = response.read().decode("utf-8") + + # Parse the CSV content + csv_reader = csv.DictReader(csv_content.splitlines()) + packages = list(csv_reader) + + logger.info(f"Successfully parsed {len(packages)} packages from CSV") + + return packages + + except Exception as e: + logger.error(f"Failed to download or parse CSV: {e}") + return [] + + +def is_mgmt_package(pkg: Dict[str, str]) -> bool: + pkg_name = pkg.get(PACKAGE_COL, "") + _type = pkg.get(TYPE_COL, "") + if _type == "mgmt": + return True + elif _type == "client": + return False + else: + return pkg_name != "azure-mgmt-core" and ( + "mgmt" in pkg_name or "cognitiveservices" in pkg_name + ) + + +def separate_packages_by_type( + packages: List[Dict[str, str]], +) -> Tuple[List[Dict[str, str]], List[Dict[str, str]]]: + """Separate packages into data plane and management plane libraries.""" + data_plane_packages = [] + mgmt_plane_packages = [] + + for pkg in packages: + if is_mgmt_package(pkg): + mgmt_plane_packages.append(pkg) + else: + data_plane_packages.append(pkg) + + logger.debug( + f"Separated {len(data_plane_packages)} data plane and {len(mgmt_plane_packages)} management plane packages" + ) + + return (data_plane_packages, mgmt_plane_packages) + + +def package_needs_update( + package_row: Dict[str, str], prev_release_date: str, is_new=False +) -> bool: + """ + Check if the package is new or needs version update (i.e., FirstGADate or LatestGADate is after the last release). + + :param package_row: The parsed CSV row for the package. + :param prev_release_date: The date of the previous release in "mm/dd/yyyy" format. + :param is_new: Whether to check for new package (FirstGADate) or outdated package (LatestGADate). + :return: if the package is new or needs an update. + """ + compare_date = ( + package_row.get(FIRST_GA_DATE_COL) + if is_new + else package_row.get(LATEST_GA_DATE_COL) + ) + + logger.debug( + f"Checking {'new package' if is_new else 'outdated package'} for package {package_row.get(PACKAGE_COL)} with against date: {compare_date}" + ) + + if not compare_date: + if not is_new and package_row.get(PACKAGE_COL) == "uamqp": + return True # uamqp is an exception + + logger.debug( + f"Package {package_row.get(PACKAGE_COL)} is skipped due to missing {FIRST_GA_DATE_COL if is_new else LATEST_GA_DATE_COL}." + ) + + return False + + try: + # Convert string dates to datetime objects for proper comparison + compare_date = datetime.strptime(compare_date, "%m/%d/%Y") + prev_date = datetime.strptime(prev_release_date, "%m/%d/%Y") + logger.debug( + f"Comparing {package_row.get(PACKAGE_COL)} CompareDate {compare_date} with previous release date {prev_date}" + ) + return compare_date > prev_date + except ValueError as e: + logger.error( + f"Date parsing error for package {package_row.get(PACKAGE_COL)}: {e}" + ) + return False + + +def get_package_data_from_pypi( + package_name: str, +) -> Tuple[Optional[str], Optional[str]]: + """Fetch the latest version and download URI for a package from PyPI.""" + pypi_url = f"https://pypi.org/pypi/{package_name}/json" + try: + with urllib.request.urlopen(pypi_url, timeout=10) as response: + data = json.loads(response.read().decode("utf-8")) + + # Get the latest version + latest_version = data["info"]["version"] + if latest_version in data["releases"] and data["releases"][latest_version]: + # Get the source distribution (sdist) if available + files = data["releases"][latest_version] + source_dist = next( + (f for f in files if f["packagetype"] == "sdist"), None + ) + if source_dist: + download_url = source_dist["url"] + logger.info( + f"Found download URL for {package_name}=={latest_version}: {download_url}" + ) + return latest_version, download_url + + except Exception as e: + logger.error(f"Failed to fetch download URI from PyPI for {package_name}: {e}") + return None, None + + +def build_package_index(conda_artifacts: List[Dict]) -> Dict[str, Tuple[int, int]]: + """Build an index of package name -> (artifact_idx, checkout_idx) for fast lookups in conda-sdk-client.yml.""" + package_index = {} + + for artifact_idx, artifact in enumerate(conda_artifacts): + if "checkout" in artifact: + for checkout_idx, checkout_item in enumerate(artifact["checkout"]): + package_name = checkout_item.get("package") + if package_name: + package_index[package_name] = (artifact_idx, checkout_idx) + return package_index diff --git a/conda/update_conda_files.py b/conda/update_conda_files.py new file mode 100644 index 000000000000..b6524874512c --- /dev/null +++ b/conda/update_conda_files.py @@ -0,0 +1,1101 @@ +"""Update package versions, yml files, release-logs, and changelogs for conda packages.""" + +import os +import argparse +import yaml +import re +import glob +from datetime import datetime +from dateutil.relativedelta import relativedelta +from ci_tools.logging import logger, configure_logging +from ci_tools.parsing import ParsedSetup +from typing import Dict, List, Optional, Tuple +from conda_helper_functions import ( + parse_csv, + separate_packages_by_type, + package_needs_update, + get_package_data_from_pypi, + build_package_index, + get_package_path, + get_bundle_name, + map_bundle_to_packages, + PACKAGE_COL, + VERSION_GA_COL, + LATEST_GA_DATE_COL, + REPO_PATH_COL, + SUPPORT_COL, +) + +# paths +ROOT_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) +SDK_DIR = os.path.join(ROOT_DIR, "sdk") +CONDA_DIR = os.path.join(ROOT_DIR, "conda") +CONDA_RECIPES_DIR = os.path.join(CONDA_DIR, "conda-recipes") +CONDA_RELEASE_LOGS_DIR = os.path.join(CONDA_DIR, "conda-releaselogs") +CONDA_ENV_PATH = os.path.join(CONDA_RECIPES_DIR, "conda_env.yml") +CONDA_CLIENT_YAML_PATH = os.path.join( + ROOT_DIR, "eng", "pipelines", "templates", "stages", "conda-sdk-client.yml" +) +CONDA_MGMT_META_YAML_PATH = os.path.join(CONDA_RECIPES_DIR, "azure-mgmt", "meta.yaml") + +# constants +RELEASE_PERIOD_MONTHS = 3 + +# packages that should be shipped but are known to be missing from the csv - store version here +PACKAGES_WITH_DOWNLOAD_URI = { + "msal": "", + "msal-extensions": "", +} + + +# ===================================== +# Helpers for updating conda_env.yml +# ===================================== + + +class quoted(str): + pass + + +def quoted_presenter(dumper, data): + """YAML presenter to force quotes around a string.""" + return dumper.represent_scalar("tag:yaml.org,2002:str", data, style="'") + + +def update_conda_version( + target_release_date: Optional[datetime] = None, +) -> Tuple[datetime, str]: + """Update the AZURESDK_CONDA_VERSION in conda_env.yml and return the old and new versions. + + Args: + target_release_date: Optional specific release date to use. If None, calculates + the next release date by adding RELEASE_PERIOD_MONTHS to the old version. + """ + + with open(CONDA_ENV_PATH, "r") as file: + conda_env_data = yaml.safe_load(file) + + old_version = conda_env_data["variables"]["AZURESDK_CONDA_VERSION"] + old_date = datetime.strptime(old_version, "%Y.%m.%d") + + if target_release_date: + new_date = target_release_date + else: + new_date = old_date + relativedelta(months=RELEASE_PERIOD_MONTHS) + + # bump version + new_version = new_date.strftime("%Y.%m.%d") + conda_env_data["variables"]["AZURESDK_CONDA_VERSION"] = quoted(new_version) + + yaml.add_representer(quoted, quoted_presenter) + + with open(CONDA_ENV_PATH, "w") as file: + yaml.dump(conda_env_data, file, default_flow_style=False, sort_keys=False) + + logger.info(f"Updated AZURESDK_CONDA_VERSION from {old_version} to {new_version}") + + return old_date, new_version + + +# ===================================== +# Helpers for updating conda-sdk-client.yml +# ===================================== + + +class IndentDumper(yaml.SafeDumper): + """Used to preserve indentation levels in conda-sdk-client.yml.""" + + def increase_indent(self, flow=False, indentless=False): + return super().increase_indent(flow, False) + + +def update_conda_sdk_client_yml( + package_dict: Dict[str, Dict[str, str]], + packages_to_update: List[str], + new_data_plane_packages: List[str], + new_mgmt_plane_packages: List[str], +) -> List[str]: + """ + Update outdated package versions and add new entries in conda-sdk-client.yml file + + :param package_dict: Dictionary mapping package names to their CSV row data. + :param packages_to_update: List of package names that need version updates. + :param new_data_plane_packages: List of new data plane package names. + :param new_mgmt_plane_packages: List of new management plane package names. + :return: List of package names that were not updated or added and may require manual action. + """ + updated_count = 0 + added_count = 0 + result = [] + + with open(CONDA_CLIENT_YAML_PATH, "r") as file: + conda_client_data = yaml.safe_load(file) + + conda_artifacts = conda_client_data["extends"]["parameters"]["stages"][0]["jobs"][ + 0 + ]["steps"][0]["parameters"]["CondaArtifacts"] + + # === Update outdated package versions === + + logger.info( + f"Detected {len(packages_to_update)} outdated package versions to update in conda-sdk-client.yml" + ) + package_index = build_package_index(conda_artifacts) + + for pkg_name in packages_to_update: + pkg = package_dict.get(pkg_name, {}) + new_version = pkg.get(VERSION_GA_COL) + if pkg_name in package_index: + artifact_idx, checkout_idx = package_index[pkg_name] + checkout_item = conda_artifacts[artifact_idx]["checkout"][checkout_idx] + + if "version" in checkout_item: + old_version = checkout_item.get("version", "") + checkout_item["version"] = new_version + logger.info(f"Updated {pkg_name}: {old_version} -> {new_version}") + updated_count += 1 + else: + logger.warning( + f"Package {pkg_name} has no 'version' field, skipping update" + ) + result.append(pkg_name) + else: + logger.warning( + f"Package {pkg_name} not found in conda-sdk-client.yml, skipping update" + ) + result.append(pkg_name) + + # handle download_uri for packages known to be missing from the csv + for pkg_name in PACKAGES_WITH_DOWNLOAD_URI: + if pkg_name in package_index: + artifact_idx, checkout_idx = package_index[pkg_name] + checkout_item = conda_artifacts[artifact_idx]["checkout"][checkout_idx] + + curr_download_uri = checkout_item.get("download_uri", "") + latest_version, download_uri = get_package_data_from_pypi(pkg_name) + + if not latest_version or not download_uri: + logger.warning( + f"Could not retrieve latest version or download URI for {pkg_name} from PyPI, skipping" + ) + result.append(pkg_name) + continue + + # store retrieved version for release log + PACKAGES_WITH_DOWNLOAD_URI[pkg_name] = latest_version + + if curr_download_uri != download_uri: + # version needs update + logger.info( + f"Package {pkg_name} download_uri mismatch with PyPi, updating {curr_download_uri} to {download_uri}" + ) + # checkout for these packages only has download_uri, no version field + checkout_item["download_uri"] = download_uri + logger.info( + f"Updated download_uri for {pkg_name} with version {latest_version}: {download_uri}" + ) + updated_count += 1 + else: + logger.warning( + f"Package {pkg_name} not found in conda-sdk-client.yml, skipping download_uri update" + ) + result.append(pkg_name) + + # === Add new data plane packages === + + logger.info( + f"Detected {len(new_data_plane_packages)} new data plane packages to add to conda-sdk-client.yml" + ) + + parameters = conda_client_data["parameters"] + + # quick look up for handling bundled package releases + existing_parameter_names = [p.get("name") for p in parameters] + existing_artifact_names = { + a.get("name"): idx for idx, a in enumerate(conda_artifacts) + } + + for package_name in new_data_plane_packages: + pkg = package_dict.get(package_name, {}) + + if package_name in package_index: + logger.warning( + f"New package {package_name} already exists in conda-sdk-client.yml, skipping addition" + ) + result.append(package_name) + continue + + # bundle info is based on pyproject.toml + bundle_name = get_bundle_name(package_name) + + if bundle_name: + # package is part of a bundle + logger.info( + f"Package {package_name} belongs to release bundle {bundle_name}" + ) + release_name = f"release_{bundle_name.replace('-', '_')}" + display_name = bundle_name + else: + # package is released individually + release_name = f"release_{package_name.replace('-', '_')}" + display_name = package_name + + # add new release parameter if not exists + if release_name not in existing_parameter_names: + logger.info(f"Adding new release parameter: {release_name}") + new_parameter = { + "name": release_name, + "displayName": display_name, + "type": "boolean", + "default": True, + } + parameters.append(new_parameter) + existing_parameter_names.append(release_name) + + # add to CondaArtifacts + curr_version = pkg.get(VERSION_GA_COL) + + if not curr_version: + logger.error( + f"Package {package_name} is missing version info, skipping addition" + ) + result.append(package_name) + continue + + checkout_package = {"package": package_name, "version": curr_version} + common_root, service_name = determine_service_info(pkg, bundle_name) + + if package_name in existing_artifact_names: + # individual released package already exists + logger.warning( + f"New package {package_name} already exists in conda-sdk-client.yml, skipping addition" + ) + result.append(package_name) + continue + + if bundle_name and bundle_name in existing_artifact_names: + # bundle already exists, will append packages to it + logger.info( + f"Release bundle {bundle_name} already exists in conda-sdk-client.yml, will append package {package_name} to it" + ) + conda_artifacts[existing_artifact_names[bundle_name]]["checkout"].append( + checkout_package + ) + else: + # no existing artifact, whether bundle or not -> create + new_artifact_entry = { + "name": bundle_name if bundle_name else package_name, + "common_root": common_root, + "service": service_name, + "in_batch": f"${{{{ parameters.{release_name} }}}}", + "checkout": [checkout_package], + } + # append before azure-mgmt entry + conda_artifacts.insert(len(conda_artifacts) - 1, new_artifact_entry) + + added_count += 1 + logger.info(f"Added new data plane package: {package_name}") + + existing_artifact_names[bundle_name if bundle_name else package_name] = ( + len(conda_artifacts) - 2 + ) # new index + + # === Add new mgmt plane packages === + + logger.info( + f"Detected {len(new_mgmt_plane_packages)} new management plane packages to add to conda-sdk-client.yml" + ) + + # assumes azure-mgmt will always be the last CondaArtifacts entry + azure_mgmt_artifact_checkout = conda_artifacts[-1]["checkout"] + + for package_name in new_mgmt_plane_packages: + pkg = package_dict.get(package_name, {}) + + if package_name in package_index: + logger.warning( + f"New package {package_name} already exists in conda-sdk-client.yml, skipping addition" + ) + result.append(package_name) + continue + + new_mgmt_entry = { + "package": package_name, + "version": pkg.get(VERSION_GA_COL), + } + + azure_mgmt_artifact_checkout.append(new_mgmt_entry) + + added_count += 1 + logger.info(f"Added new management plane package: {package_name}") + + # sort mgmt packages alphabetically + azure_mgmt_artifact_checkout.sort(key=lambda x: x["package"]) + + if updated_count > 0 or added_count > 0: + with open(CONDA_CLIENT_YAML_PATH, "w") as file: + yaml.dump( + conda_client_data, + file, + Dumper=IndentDumper, + default_flow_style=False, + sort_keys=False, + indent=2, + width=float("inf"), + ) + logger.info( + f"Successfully updated {updated_count} package versions in conda-sdk-client.yml" + ) + else: + logger.warning("No packages were found in the YAML file to update") + return result + + +# ===================================== +# Helpers for creating conda-recipes//meta.yaml files +# ===================================== + + +def determine_service_info( + pkg: Dict[str, str], bundle_name: Optional[str] +) -> Tuple[str, str]: + """ + Returns the common root and service name for the given package. + + :param package_name: The name of the package (e.g., "azure-ai-textanalytics"). + :param bundle_name: The name of the bundle/release group the package belongs to, if any. + """ + # defaults + package_name = pkg.get(PACKAGE_COL, "") + service_name = pkg.get(REPO_PATH_COL, "").lower() + + if bundle_name: + common_root = f"azure/{bundle_name.split('-')[1]}" + else: + common_root = "azure" + + package_path = get_package_path(package_name) + if not service_name and package_path: + service_name = os.path.basename(os.path.dirname(package_path)) + + return common_root, service_name + + +def format_requirement(req: str) -> str: + """Format a requirement string for conda meta.yaml.""" + name_unpinned = re.split(r"[>=={{{{ environ.get('AZURESDK_CONDA_VERSION', '0.0.0') }}}}" + + # filter out ~ for yml format + req = req.replace("~", "") + return req + + +def get_package_requirements(parsed: ParsedSetup) -> Tuple[List[str], List[str]]: + """Retrieve the host and run requirements for a data plane package meta.yaml.""" + host_requirements = set(["pip"]) + run_requirements = set() + + # reqs commonly seen in existing meta.yaml files that aren't always in setup.py or pyproject.toml + for essential_req in [ + "azure-identity", + "azure-core", + "python", + "aiohttp", + "requests-oauthlib >=0.5.0", + "cryptography", + ]: + req_name = format_requirement(essential_req) + host_requirements.add(req_name) + run_requirements.add(req_name) + + package_path = get_package_path(parsed.name) + if not package_path: + logger.error(f"Could not find package path for {parsed.name}") + return list(host_requirements), list(run_requirements) + + # get requirements from setup.py or pyproject.toml + install_reqs = parsed.requires + + for req in install_reqs: + req_name = format_requirement(req) + host_requirements.add(req_name) + run_requirements.add(req_name) + + return list(host_requirements), list(run_requirements) + + +def get_package_metadata( + package_name: str, package_path: Optional[str], is_bundle: bool = False +) -> Tuple[str, str, str]: + """Extract package metadata for about section in meta.yaml. + + :param package_name: The name of the package or bundle. + :param package_path: The filesystem path to the package. + :param is_bundle: Whether this is a release bundle (affects URL structure). + """ + if package_path: + service_dir = os.path.basename(os.path.dirname(package_path)) + else: + service_dir = package_name.replace("azure-", "") + + # For bundles, URL points to service directory; for individual packages, include package name + if is_bundle: + home_url = ( + f"https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/{service_dir}" + ) + else: + home_url = f"https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/{service_dir}/{package_name}" + + summary = f"Microsoft Azure {package_name.replace('azure-', '').replace('-', ' ').title()} Client Library for Python" + + conda_url = f"https://aka.ms/azsdk/conda/releases/{service_dir}" + description = ( + f"This is the {summary}.\n Please see {conda_url} for version details." + ) + + return home_url, summary, description + + +def generate_data_plane_meta_yaml( + bundle_map: Dict[str, List[str]], + package_name: str, + bundle_name: Optional[str], +) -> str: + """ + Generate the meta.yaml content for a data plane package or release group. + """ + # assumes env var name is arbitrary and replaced in conda_functions.py + src_distr_name = package_name.split("-")[-1].upper() + src_distribution_env_var = f"{src_distr_name}_SOURCE_DISTRIBUTION" + + # TODO not sure if this is the best way to get these requirements + # TODO don't think this covers all possible import tests, e.g. azure.eventgrid, azure.eventgrid.aio <- when would I add that? + if bundle_name: + # handle grouped packages + logger.info( + f"Generating meta.yaml for release group {bundle_name} including packages: {bundle_map[bundle_name]}" + ) + host_reqs = set() + run_reqs = set() + pkg_imports = [] + + for pkg in bundle_map[bundle_name]: + package_path = get_package_path(pkg) + parsed_setup = ParsedSetup.from_path(package_path) + + pkg_host_reqs, pkg_run_reqs = get_package_requirements(parsed_setup) + host_reqs.update(pkg_host_reqs) + run_reqs.update(pkg_run_reqs) + + pkg_imports.append(pkg.replace("-", ".")) + host_reqs = list(host_reqs) + run_reqs = list(run_reqs) + + package_path = get_package_path(bundle_map[bundle_name][0]) + home_url, summary, description = get_package_metadata( + bundle_name, package_path, is_bundle=True + ) + else: + logger.info(f"Generating meta.yaml for package {package_name}") + package_path = get_package_path(package_name) + parsed_setup = ParsedSetup.from_path(package_path) + + host_reqs, run_reqs = get_package_requirements(parsed_setup) + pkg_imports = [package_name.replace("-", ".")] + + home_url, summary, description = get_package_metadata( + package_name, package_path + ) + + # Format requirements with proper YAML indentation + host_reqs_str = "\n - ".join(host_reqs) + run_reqs_str = "\n - ".join(run_reqs) + pkg_imports_str = "\n - ".join(pkg_imports) + meta_yaml_content = f"""{{% set name = "{package_name}" %}} + +package: + name: "{{{{ name|lower }}}}" + version: {{{{ environ.get('AZURESDK_CONDA_VERSION', '0.0.0') }}}} + +source: + url: {{{{ environ.get('{src_distribution_env_var}', '') }}}} + +build: + noarch: python + number: 0 + script: "{{{{ PYTHON }}}} -m pip install . -vv" + +requirements: + host: + - {host_reqs_str} + run: + - {run_reqs_str} + +test: + imports: + - {pkg_imports_str} + +about: + home: "{home_url}" + license: MIT + license_family: MIT + license_file: + summary: "{summary}" + description: | + {description} + doc_url: + dev_url: + +extra: + recipe-maintainers: + - xiangyan99 +""" + return meta_yaml_content + + +def add_new_data_plane_packages( + package_dict: Dict[str, Dict[str, str]], + bundle_map: Dict[str, List[str]], + new_data_plane_names: List[str], +) -> List[str]: + """Create meta.yaml files for new data plane packages and add import tests.""" + if len(new_data_plane_names) == 0: + return [] + + logger.info(f"Adding {len(new_data_plane_names)} new data plane packages") + result = [] + + # bundles are processed once when encountering the first package in that group + bundles_processed = set() + for package_name in new_data_plane_names: + logger.info(f"Adding new data plane meta.yaml for: {package_name}") + + pkg_yaml_path = os.path.join(CONDA_RECIPES_DIR, package_name, "meta.yaml") + os.makedirs(os.path.dirname(pkg_yaml_path), exist_ok=True) + + bundle_name = get_bundle_name(package_name) + + if bundle_name and bundle_name in bundles_processed: + logger.info( + f"Meta.yaml for bundle {bundle_name} already created, skipping {package_name}" + ) + continue + + try: + meta_yml = generate_data_plane_meta_yaml( + bundle_map, package_name, bundle_name + ) + if bundle_name: + bundles_processed.add(bundle_name) + except Exception as e: + logger.error( + f"Failed to generate meta.yaml content for {package_name} and skipping, error: {e}" + ) + result.append(package_name) + continue + + try: + with open(pkg_yaml_path, "w") as f: + f.write(meta_yml) + logger.info(f"Created meta.yaml for {package_name} at {pkg_yaml_path}") + except Exception as e: + logger.error(f"Failed to create meta.yaml for {package_name}: {e}") + result.append(package_name) + + return result + + +# ===================================== +# Helpers for adding new mgmt plane packages to azure-mgmt/meta.yaml +# ===================================== + + +def add_new_mgmt_plane_packages( + package_dict: Dict[str, Dict[str, str]], new_mgmt_plane_names: List[str] +) -> List[str]: + """Update azure-mgmt/meta.yaml with new management libraries, and add import tests.""" + if len(new_mgmt_plane_names) == 0: + return [] + logger.info(f"Adding {len(new_mgmt_plane_names)} new management plane packages") + result = [] + + # can't use pyyaml due to jinja2 + with open(CONDA_MGMT_META_YAML_PATH, "r") as file: + content = file.read() + + test_match = re.search( + r"^test:\s*\n\s*imports:(.*?)^(?=\w)", content, re.MULTILINE | re.DOTALL + ) + if not test_match: + logger.error("Could not find 'test: imports:' section in meta.yaml") + result.extend(new_mgmt_plane_names) + return result + + existing_imports_text = test_match.group(1) + existing_imports = [ + line.strip() + for line in existing_imports_text.strip().split("\n") + if line.strip().startswith("-") + ] + + new_imports = [] + for package_name in new_mgmt_plane_names: + if not package_name: + logger.warning("Skipping package with missing name") + continue + + module_name = package_name.replace("-", ".") + + imports = [ + f"- {module_name}", + f"- {module_name}.aio", + f"- {module_name}.aio.operations", + f"- {module_name}.models", + f"- {module_name}.operations", + ] + + new_imports.extend(imports) + logger.info(f"Generated import statements for {package_name}") + + all_imports = list(set(existing_imports + new_imports)) + + # sort alphabetically + all_imports.sort() + + # format imports with proper indentation + formatted_imports = "\n".join(f" {imp}" for imp in all_imports) + + # replace the imports section + new_imports_section = f"test:\n imports:\n{formatted_imports}\n\n" + updated_content = re.sub( + r"^test:\s*\n\s*imports:.*?^(?=\w)", + new_imports_section, + content, + flags=re.MULTILINE | re.DOTALL, + ) + + try: + with open(CONDA_MGMT_META_YAML_PATH, "w") as file: + file.write(updated_content) + except Exception as e: + logger.error(f"Failed to update {CONDA_MGMT_META_YAML_PATH}: {e}") + result.extend(new_mgmt_plane_names) + + logger.info( + f"Added {len(new_mgmt_plane_names)} new management plane packages to meta.yaml" + ) + return result + + +# ===================================== +# Helpers for updating release logs +# ===================================== + + +def update_data_plane_release_logs( + package_dict: Dict, + bundle_map: Dict[str, List[str]], + new_data_plane_names: List[str], + release_date: str, +) -> List[str]: + """ + Add and update release logs for data plane conda packages. Release log includes versions of all packages for the release + """ + result = [] + + # Update all existing data plane release logs by file + + existing_release_logs = glob.glob(os.path.join(CONDA_RELEASE_LOGS_DIR, "*.md")) + for release_log_path in existing_release_logs: + curr_service_name = os.path.basename(release_log_path).replace(".md", "") + # skip azure-mgmt here + if curr_service_name == "azure-mgmt": + continue + if ( + curr_service_name not in package_dict + and curr_service_name not in bundle_map + and curr_service_name not in PACKAGES_WITH_DOWNLOAD_URI + ): + logger.warning( + f"Existing release log service {curr_service_name} was not found in CSV data, skipping update. It may be deprecated." + ) + result.append(curr_service_name) + continue + + pkg_updates = [] + if curr_service_name in bundle_map: + # handle grouped packages + pkg_names_in_bundle = bundle_map[curr_service_name] + for pkg_name in pkg_names_in_bundle: + pkg = package_dict.get(pkg_name, {}) + version = pkg.get(VERSION_GA_COL) + if version: + pkg_updates.append(f"- {pkg_name}-{version}") + else: + logger.warning( + f"Package {pkg_name} in group {curr_service_name} is missing version info, it may be deprecated. Skipping in release log update" + ) + result.append(pkg_name) + else: + # handle exception for packages with download_uri + if curr_service_name in PACKAGES_WITH_DOWNLOAD_URI: + version = PACKAGES_WITH_DOWNLOAD_URI[curr_service_name] + if not version: + logger.warning( + f"Package {curr_service_name} with download_uri is missing version info, it may be deprecated. Skipping in release log update" + ) + result.append(curr_service_name) + continue + else: + pkg = package_dict.get(curr_service_name, {}) + version = pkg.get(VERSION_GA_COL) + + if version: + pkg_updates.append(f"- {curr_service_name}-{version}") + else: + logger.warning( + f"Package {curr_service_name} is missing version info, it may be deprecated. Skipping in release log update" + ) + result.append(curr_service_name) + try: + with open(release_log_path, "r") as f: + existing_content = f.read() + + lines = existing_content.split("\n") + + new_release = f"\n## {release_date}\n\n" + + # check if release is already logged + if new_release in existing_content: + logger.info( + f"Release log for {curr_service_name} already contains entry for {release_date}, overwriting" + ) + # remove existing release section to overwrite + release_idx = lines.index(new_release.strip()) + + ## find next release heading or end of file + next_release_idx = next( + ( + i + for i in range(release_idx + 1, len(lines)) + if lines[i].startswith("## ") + ), + len(lines), + ) + del lines[release_idx:next_release_idx] + + new_release += "### Packages included\n\n" + new_release += "\n".join(pkg_updates) + lines.insert(1, new_release) + + updated_content = "\n".join(lines) + + with open(release_log_path, "w") as f: + f.write(updated_content) + + logger.info(f"Updated release log for {os.path.basename(release_log_path)}") + except Exception as e: + logger.error( + f"Failed to update release log {os.path.basename(release_log_path)}: {e}" + ) + result.append(curr_service_name) + + # Handle brand new packages + for package_name in new_data_plane_names: + pkg = package_dict.get(package_name, {}) + version = pkg.get(VERSION_GA_COL) + + if not version: + logger.warning(f"Skipping {package_name} with missing version") + result.append(package_name) + continue + + bundle_name = get_bundle_name(package_name) + # check for bundle + if bundle_name: + release_log_path = os.path.join(CONDA_RELEASE_LOGS_DIR, f"{bundle_name}.md") + else: + release_log_path = os.path.join( + CONDA_RELEASE_LOGS_DIR, f"{package_name}.md" + ) + bundle_name = package_name # for release log logic below + + if not os.path.exists(release_log_path): + # Add brand new release log file + logger.info(f"Creating new release log for: {bundle_name}") + + title_parts = bundle_name.replace("azure-", "").split("-") + title = " ".join(word.title() for word in title_parts) + + content = f"# Azure {title} client library for Python (conda)\n\n" + content += f"## {release_date}\n\n" + content += "### Packages included\n\n" + + pkg_updates = [] + if bundle_name: + pkg_names_in_log = bundle_map.get(bundle_name, []) + for pkg_name in pkg_names_in_log: + pkg = package_dict.get(pkg_name, {}) + version = pkg.get(VERSION_GA_COL) + pkg_updates.append(f"- {pkg_name}-{version}") + else: + pkg = package_dict.get(package_name, {}) + version = pkg.get(VERSION_GA_COL) + pkg_updates.append(f"- {package_name}-{version}") + content += "\n".join(pkg_updates) + + try: + with open(release_log_path, "w") as f: + f.write(content) + logger.info(f"Created new release log for {bundle_name}") + except Exception as e: + logger.error(f"Failed to create release log for {bundle_name}: {e}") + result.append(bundle_name) + + else: + logger.info( + f"Release log for {bundle_name} already exists, check that new package {package_name} is included" + ) + + return result + + +def update_mgmt_plane_release_log( + package_dict: Dict, + all_mgmt_plane_names: List[str], + release_date: str, +) -> List[str]: + """ + Update azure-mgmt release log. + """ + result = [] + + mgmt_log_path = os.path.join(CONDA_RELEASE_LOGS_DIR, "azure-mgmt.md") + if not os.path.exists(mgmt_log_path): + logger.error("Management plane release log azure-mgmt.md does not exist.") + return all_mgmt_plane_names # all new packages need attention + + pkg_updates = [] + for package_name in all_mgmt_plane_names: + pkg = package_dict.get(package_name, {}) + version = pkg.get(VERSION_GA_COL) + + if not version: + logger.warning( + f"Skipping release log update of {package_name} with missing version" + ) + result.append(package_name) + continue + + pkg_updates.append(f"- {package_name}-{version}") + + try: + with open(mgmt_log_path, "r") as f: + existing_content = f.read() + + lines = existing_content.split("\n") + + new_release = f"\n## {release_date}\n\n" + + # check if release is already logged + if new_release in existing_content: + logger.info( + f"Release log for azure-mgmt already contains entry for {release_date}, overwriting" + ) + # remove existing release section to overwrite + release_idx = lines.index(new_release.strip()) + + ## find next release heading or end of file + next_release_idx = next( + ( + i + for i in range(release_idx + 1, len(lines)) + if lines[i].startswith("## ") + ), + len(lines), + ) + del lines[release_idx:next_release_idx] + + new_release += "### Packages included\n\n" + + new_release += "\n".join(pkg_updates) + lines.insert(1, new_release) + updated_content = "\n".join(lines) + + with open(mgmt_log_path, "w") as f: + f.write(updated_content) + except Exception as e: + logger.error(f"Failed to update azure-mgmt release log: {e}") + return all_mgmt_plane_names + + return result + + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + description="Update conda package files and versions for release." + ) + parser.add_argument( + "--verbose", + action="store_true", + help="Enable debug logging", + ) + parser.add_argument( + "--release-date", + type=str, + default=None, + help="Release date in 'MM.DD' format (e.g., '03.01', '12.01'). " + "Year is determined automatically. If not provided, the next release date is calculated.", + ) + + args = parser.parse_args() + configure_logging(args) + + # Handle release date + if args.release_date: + try: + current_year = datetime.now().year + target_release_date = datetime.strptime( + f"{current_year}.{args.release_date}", "%Y.%m.%d" + ) + logger.info( + f"Using provided release date: {target_release_date.strftime('%Y.%m.%d')}" + ) + except ValueError as e: + logger.error(f"Invalid release date format '{args.release_date}': {e}") + logger.error("Expected format: 'MM.DD' (e.g., '03.01', '12.01')") + exit(1) + else: + logger.info( + "No release date provided, auto bumping old date by {} months.".format( + RELEASE_PERIOD_MONTHS + ) + ) + target_release_date = None + + old_date, new_version = update_conda_version(target_release_date) + + # Output version as Azure DevOps pipeline variable to use in PR + print(f"##vso[task.setvariable variable=CondaReleaseVersion]{new_version}") + + # convert to mm/dd/yyyy format for comparison with CSV dates + old_version = old_date.strftime("%m/%d/%Y") + + packages = parse_csv() + if not packages: + logger.error("No packages found in CSV data.") + exit(1) + + # Only ship GA packages that are not deprecated + packages = [ + pkg + for pkg in packages + if ( + (pkg.get(VERSION_GA_COL) and pkg.get(LATEST_GA_DATE_COL)) + and not pkg.get(SUPPORT_COL) == "deprecated" + ) + ] + logger.info(f"Filtered to {len(packages)} GA packages") + + data_pkgs, mgmt_pkgs = separate_packages_by_type(packages) + + outdated_data_plane_names = [ + pkg.get(PACKAGE_COL, "") + for pkg in data_pkgs + if package_needs_update(pkg, old_version, is_new=False) + ] + new_data_plane_names = [ + pkg.get(PACKAGE_COL, "") + for pkg in data_pkgs + if package_needs_update(pkg, old_version, is_new=True) + ] + outdated_mgmt_plane_names = [ + pkg.get(PACKAGE_COL, "") + for pkg in mgmt_pkgs + if package_needs_update(pkg, old_version, is_new=False) + ] + new_mgmt_plane_names = [ + pkg.get(PACKAGE_COL, "") + for pkg in mgmt_pkgs + if package_needs_update(pkg, old_version, is_new=True) + ] + + # don't overlap new packages with outdated packages + outdated_data_plane_names = [ + name for name in outdated_data_plane_names if name not in new_data_plane_names + ] + outdated_mgmt_plane_names = [ + name for name in outdated_mgmt_plane_names if name not in new_mgmt_plane_names + ] + + # map package name to csv row for easy lookup + package_dict = {pkg.get(PACKAGE_COL, ""): pkg for pkg in packages} + + outdated_package_names = outdated_data_plane_names + outdated_mgmt_plane_names + + # update conda-sdk-client.yml + conda_sdk_client_pkgs_result = update_conda_sdk_client_yml( + package_dict, outdated_package_names, new_data_plane_names, new_mgmt_plane_names + ) + + # pre-process bundled packages to minimize file writes for new data plane packages, + # and release logs + bundle_map = map_bundle_to_packages(list(package_dict.keys())) + logger.info( + f"Identified {len(bundle_map)} release bundles from package data: {bundle_map}" + ) + + # handle new data plane libraries + new_data_plane_results = add_new_data_plane_packages( + package_dict, bundle_map, new_data_plane_names + ) + + # handle new mgmt plane libraries + new_mgmt_plane_results = add_new_mgmt_plane_packages( + package_dict, new_mgmt_plane_names + ) + + # add/update release logs + data_plane_release_log_results = update_data_plane_release_logs( + package_dict, bundle_map, new_data_plane_names, new_version + ) + + all_mgmt_plane_names = [pkg.get(PACKAGE_COL, "") for pkg in mgmt_pkgs] + + mgmt_plane_release_log_results = update_mgmt_plane_release_log( + package_dict, all_mgmt_plane_names, new_version + ) + + print("=== REPORT ===") + + if conda_sdk_client_pkgs_result: + print( + "The following packages may require manual adjustments in conda-sdk-client.yml:" + ) + for pkg_name in conda_sdk_client_pkgs_result: + print(f"- {pkg_name}") + + if new_data_plane_results: + print( + "\nThe following new data plane packages may require manual meta.yaml creation or adjustments:" + ) + for pkg_name in new_data_plane_results: + print(f"- {pkg_name}") + + if new_mgmt_plane_results: + print( + "\nThe following new management plane packages may require manual adjustments in azure-mgmt/meta.yaml:" + ) + for pkg_name in new_mgmt_plane_results: + print(f"- {pkg_name}") + + if data_plane_release_log_results: + print( + "\nThe following data plane packages may require manual adjustments in release logs:" + ) + for pkg_name in data_plane_release_log_results: + print(f"- {pkg_name}") diff --git a/eng/pipelines/conda-update-pipeline.yml b/eng/pipelines/conda-update-pipeline.yml new file mode 100644 index 000000000000..2b2672c06825 --- /dev/null +++ b/eng/pipelines/conda-update-pipeline.yml @@ -0,0 +1,121 @@ +trigger: none +pr: none + +parameters: + - name: releaseDate + displayName: Release Date (MM.DD) + type: string + default: 'auto' + values: + - auto + - 03.01 + - 06.01 + - 09.01 + - 12.01 + - name: dryRun + displayName: Dry Run (skip PR submission) + type: boolean + default: false + +# Scheduled to run a week before each quarterly release +schedules: + - cron: "0 0 24 11 *" + displayName: Pre-December Quarterly Release + branches: + include: + - main + always: true + - cron: "0 0 22 2 *" + displayName: Pre-March Quarterly Release + branches: + include: + - main + always: true + - cron: "0 0 25 5 *" + displayName: Pre-June Quarterly Release + branches: + include: + - main + always: true + - cron: "0 0 25 8 *" + displayName: Pre-September Quarterly Release + branches: + include: + - main + always: true + +extends: + template: /eng/pipelines/templates/stages/1es-redirect.yml + parameters: + stages: + - stage: UpdateCondaFiles + displayName: Update Conda Files + + jobs: + - job: UpdateCondaFilesJob + timeoutInMinutes: 90 + displayName: Update Conda Files and Submit PR + variables: + - template: /eng/pipelines/templates/variables/globals.yml + - name: ReleaseDate + ${{ if eq(parameters.releaseDate, 'auto') }}: + ${{ if contains(variables['Build.CronSchedule.DisplayName'], 'December') }}: + value: '12.01' + ${{ elseif contains(variables['Build.CronSchedule.DisplayName'], 'March') }}: + value: '03.01' + ${{ elseif contains(variables['Build.CronSchedule.DisplayName'], 'June') }}: + value: '06.01' + ${{ elseif contains(variables['Build.CronSchedule.DisplayName'], 'September') }}: + value: '09.01' + ${{ else }}: + value: 'Unknown' + ${{ else }}: + value: ${{ parameters.releaseDate }} + + pool: + name: azsdk-pool + image: ubuntu-24.04 + os: linux + + steps: + - checkout: self + persistCredentials: true + + - task: UsePythonVersion@0 + displayName: 'Use Python 3.11' + inputs: + versionSpec: '3.11' + + - script: | + python -m pip install --upgrade pip + python -m pip install "eng/tools/azure-sdk-tools[build]" + python -m pip install python-dateutil + displayName: 'Prep Environment' + + - script: | + if [ "$(ReleaseDate)" != "Unknown" ]; then + python conda/update_conda_files.py --release-date "$(ReleaseDate)" + else + python conda/update_conda_files.py + fi + displayName: 'Update Conda Files' + + - ${{ if eq(parameters.dryRun, false) }}: + - template: /eng/common/pipelines/templates/steps/create-pull-request.yml + parameters: + PRBranchName: conda-update-$(Build.BuildId) + CommitMsg: 'Update conda files for $(CondaReleaseVersion) release' + PRTitle: 'Conda Release $(CondaReleaseVersion) generated by $(Build.BuildId)' + PRBody: | + This PR was automatically generated to update Conda files for a new release. + + - Updates outdated package versions in conda-sdk-client.yml + - Adds new packages to conda-sdk-client.yml + - Adds/updates yamls and changelogs + + ## Next Steps + - [ ] For new data plane packages, submit this form to create a private dummy library placeholder in Conda before uploading a release: https://forms.office.com/Pages/ResponsePage.aspx?id=v4j5cvGGr0GRqy180BHbR180k2XpSUFBtXHTh8-jMUlUNlA1MFpZOVhZME1aNU1EU1Y3SjZRU0JNRC4u + - [ ] After this PR is merged and succeeds the Conda build, approve the pipeline to upload the releases to Conda + - [ ] After upload, delete the dummy library and make the new packages publicly available in Conda. + - [ ] Create an AKA link for new release logs here: http://aka.ms/ + BaseBranchName: main diff --git a/eng/pipelines/templates/stages/conda-sdk-client.yml b/eng/pipelines/templates/stages/conda-sdk-client.yml index 98b6811d2600..b2700a67e7be 100644 --- a/eng/pipelines/templates/stages/conda-sdk-client.yml +++ b/eng/pipelines/templates/stages/conda-sdk-client.yml @@ -1,185 +1,184 @@ parameters: - name: release_msal - displayName: 'msal' + displayName: msal type: boolean default: true - name: release_msal_extensions - displayName: 'msal-extensions' + displayName: msal-extensions type: boolean default: true - name: release_azure_core - displayName: 'azure-core' + displayName: azure-core type: boolean default: true - name: release_azure_identity - displayName: 'azure-identity' + displayName: azure-identity type: boolean default: true - name: release_azure_healthinsights - displayName: 'azure-healthinsights' + displayName: azure-healthinsights type: boolean default: true - name: release_azure_storage - displayName: 'azure-storage' + displayName: azure-storage type: boolean default: true - name: release_azure_ai_contentsafety - displayName: 'azure-ai-contentsafety' + displayName: azure-ai-contentsafety type: boolean default: true - name: release_azure_ai_evaluation - displayName: 'azure-ai-evaluation' + displayName: azure-ai-evaluation type: boolean default: false - name: release_azure_ai_formrecognizer - displayName: 'azure-ai-formrecognizer' + displayName: azure-ai-formrecognizer type: boolean default: false - name: release_azure_ai_language_conversations - displayName: 'azure-ai-language-conversations' + displayName: azure-ai-language-conversations type: boolean default: true - name: release_azure_ai_language_questionanswering - displayName: 'azure-ai-language-questionanswering' + displayName: azure-ai-language-questionanswering type: boolean default: true - name: release_azure_ai_ml - displayName: 'azure-ai-ml' + displayName: azure-ai-ml type: boolean default: true - name: release_azure_ai_textanalytics - displayName: 'azure-ai-textanalytics' + displayName: azure-ai-textanalytics type: boolean default: true - name: release_azure_ai_translation_document - displayName: 'azure-ai-translation-document' + displayName: azure-ai-translation-document type: boolean default: true - name: release_azure_ai_translation_text - displayName: 'azure-ai-translation-text' + displayName: azure-ai-translation-text type: boolean default: true - name: release_azure_ai_vision - displayName: 'azure-ai-vision' + displayName: azure-ai-vision type: boolean default: true - name: release_azure_ai_voicelive - displayName: 'azure-ai-voicelive' + displayName: azure-ai-voicelive type: boolean default: true - name: release_azure_appconfiguration - displayName: 'azure-appconfiguration' + displayName: azure-appconfiguration type: boolean default: true - name: release_azure_appconfiguration_provider - displayName: 'azure-appconfiguration-provider' + displayName: azure-appconfiguration-provider type: boolean default: true - name: release_azure_communication - displayName: 'azure-communication' + displayName: azure-communication type: boolean default: true - name: release_azure_confidentialledger - displayName: 'azure-confidentialledger' + displayName: azure-confidentialledger type: boolean default: true - name: release_azure_containerregistry - displayName: 'azure-containerregistry' + displayName: azure-containerregistry type: boolean default: true - name: release_azure_cosmos - displayName: 'azure-cosmos' + displayName: azure-cosmos type: boolean default: true - name: release_azure_data_tables - displayName: 'azure-data-tables' + displayName: azure-data-tables type: boolean default: true - name: release_azure_developer_loadtesting - displayName: 'azure-developer-loadtesting' + displayName: azure-developer-loadtesting type: boolean default: true - name: release_azure_digitaltwins_core - displayName: 'azure-digitaltwins-core' + displayName: azure-digitaltwins-core type: boolean default: true - name: release_azure_eventgrid - displayName: 'azure-eventgrid' + displayName: azure-eventgrid type: boolean default: true - name: release_azure_eventhub - displayName: 'azure-eventhub' + displayName: azure-eventhub type: boolean default: true - name: release_azure_iot_deviceupdate - displayName: 'azure-iot-deviceupdate' + displayName: azure-iot-deviceupdate type: boolean default: true - name: release_azure_keyvault - displayName: 'azure-keyvault' + displayName: azure-keyvault type: boolean default: true - name: release_azure_messaging_webpubsubservice - displayName: 'azure-messaging-webpubsubservice' + displayName: azure-messaging-webpubsubservice type: boolean default: true - name: release_azure_messaging_webpubsubclient - displayName: 'azure-messaging-webpubsubclient' + displayName: azure-messaging-webpubsubclient type: boolean default: true - name: release_azure_monitor_query - displayName: 'azure-monitor-query' + displayName: azure-monitor-query type: boolean default: true - name: release_azure_monitor_ingestion - displayName: 'azure-monitor-ingestion' + displayName: azure-monitor-ingestion type: boolean default: true - name: release_azure_schemaregistry - displayName: 'azure-schemaregistry' + displayName: azure-schemaregistry type: boolean default: true - name: release_azure_search_documents - displayName: 'azure-search-documents' + displayName: azure-search-documents type: boolean default: true - name: release_azure_security_attestation - displayName: 'azure-security-attestation' + displayName: azure-security-attestation type: boolean default: true - name: release_azure_servicebus - displayName: 'azure-servicebus' + displayName: azure-servicebus type: boolean default: true - name: release_azure_ai_documentintelligence - displayName: 'azure-ai-documentintelligence' + displayName: azure-ai-documentintelligence type: boolean default: true - name: release_azure_health_deidentification - displayName: 'azure-health-deidentification' + displayName: azure-health-deidentification type: boolean default: true - name: release_azure_ai_agents - displayName: 'azure-ai-agents' + displayName: azure-ai-agents type: boolean default: true - name: release_azure_ai_projects - displayName: 'azure-ai-projects' + displayName: azure-ai-projects type: boolean default: true - name: release_azure_monitor_querymetrics - displayName: 'azure-monitor-querymetrics' + displayName: azure-monitor-querymetrics type: boolean default: true - name: release_azure_monitor_opentelemetry - displayName: 'azure-monitor-opentelemetry' + displayName: azure-monitor-opentelemetry type: boolean default: true - name: release_azure_mgmt - displayName: 'azure-mgmt' + displayName: azure-mgmt type: boolean default: true - extends: template: /eng/pipelines/templates/stages/1es-redirect.yml parameters: @@ -188,18 +187,14 @@ extends: displayName: Build Universal Conda Packages variables: - template: /eng/pipelines/templates/variables/globals.yml@self - jobs: - - job: 'Build' + - job: Build timeoutInMinutes: 240 - pool: name: azsdk-pool image: ubuntu-24.04 os: linux - steps: - - template: /eng/pipelines/templates/steps/build-conda-artifacts.yml@self parameters: CondaArtifacts: @@ -209,7 +204,7 @@ extends: in_batch: ${{ parameters.release_azure_core }} checkout: - package: azure-core - version: 1.36.0 + version: 1.38.0 - package: azure-mgmt-core version: 1.6.0 - package: azure-common @@ -244,13 +239,13 @@ extends: service: storage checkout: - package: azure-storage-blob - version: 12.27.1 + version: 12.28.0 - package: azure-storage-queue - version: 12.14.1 + version: 12.15.0 - package: azure-storage-file-share - version: 12.23.1 + version: 12.24.0 - package: azure-storage-file-datalake - version: 12.22.0 + version: 12.23.0 - name: azure-ai-ml service: ml in_batch: ${{ parameters.release_azure_ai_ml }} @@ -258,7 +253,7 @@ extends: - conda-forge checkout: - package: azure-ai-ml - version: 1.30.0 + version: 1.31.0 - name: azure-ai-contentsafety common_root: azure service: contentsafety @@ -272,7 +267,7 @@ extends: in_batch: ${{ parameters.release_azure_ai_evaluation }} checkout: - package: azure-ai-evaluation - version: 1.13.5 + version: 1.14.0 - name: azure-ai-formrecognizer common_root: azure service: formrecognizer @@ -323,7 +318,7 @@ extends: in_batch: ${{ parameters.release_azure_appconfiguration }} checkout: - package: azure-appconfiguration - version: 1.7.2 + version: 1.8.0 - name: azure-appconfiguration-provider service: appconfiguration in_batch: ${{ parameters.release_azure_appconfiguration_provider }} @@ -370,7 +365,7 @@ extends: in_batch: ${{ parameters.release_azure_cosmos }} checkout: - package: azure-cosmos - version: 4.14.1 + version: 4.14.5 - name: azure-data-tables service: tables in_batch: ${{ parameters.release_azure_data_tables }} @@ -448,7 +443,7 @@ extends: in_batch: ${{ parameters.release_azure_monitor_opentelemetry }} checkout: - package: azure-monitor-opentelemetry - version: 1.8.4 + version: 1.8.5 - name: azure-monitor-query service: monitor in_batch: ${{ parameters.release_azure_monitor_query }} @@ -558,7 +553,7 @@ extends: - package: azure-mgmt-automation version: 1.0.0 - package: azure-mgmt-avs - version: 9.1.0 + version: 10.0.0 - package: azure-mgmt-azurearcdata version: 1.0.0 - package: azure-mgmt-azurestack @@ -588,9 +583,9 @@ extends: - package: azure-mgmt-commerce version: 6.0.0 - package: azure-mgmt-communication - version: 2.1.0 + version: 2.2.0 - package: azure-mgmt-compute - version: 37.0.1 + version: 37.2.0 - package: azure-mgmt-computefleet version: 1.0.0 - package: azure-mgmt-computeschedule @@ -635,6 +630,8 @@ extends: version: 2.0.1 - package: azure-mgmt-datashare version: 1.0.0 + - package: azure-mgmt-dellstorage + version: 1.0.0 - package: azure-mgmt-deploymentmanager version: 1.0.0 - package: azure-mgmt-desktopvirtualization @@ -703,16 +700,16 @@ extends: version: 1.4.0 - package: azure-mgmt-informaticadatamanagement version: 1.0.0 + - package: azure-mgmt-iotfirmwaredefense + version: 2.0.0 - package: azure-mgmt-iothub version: 4.0.0 - package: azure-mgmt-iothubprovisioningservices version: 1.1.0 - - package: azure-mgmt-iotfirmwaredefense - version: 2.0.0 - package: azure-mgmt-iotoperations version: 1.0.0 - package: azure-mgmt-keyvault - version: 12.1.1 + version: 13.0.0 - package: azure-mgmt-kubernetesconfiguration version: 3.1.0 - package: azure-mgmt-kusto @@ -724,7 +721,7 @@ extends: - package: azure-mgmt-loadtesting version: 1.0.0 - package: azure-mgmt-loganalytics - version: 12.0.0 + version: 13.1.1 - package: azure-mgmt-logic version: 10.0.0 - package: azure-mgmt-logz @@ -768,7 +765,7 @@ extends: - package: azure-mgmt-networkanalytics version: 1.0.0 - package: azure-mgmt-networkcloud - version: 2.1.0 + version: 2.2.0 - package: azure-mgmt-newrelicobservability version: 1.1.0 - package: azure-mgmt-nginx @@ -829,10 +826,10 @@ extends: version: 2.3.0 - package: azure-mgmt-resource version: 24.0.0 - - package: azure-mgmt-resourcegraph - version: 8.0.1 - package: azure-mgmt-resourceconnector version: 1.0.0 + - package: azure-mgmt-resourcegraph + version: 8.0.1 - package: azure-mgmt-resourcemover version: 1.1.0 - package: azure-mgmt-scvmm @@ -905,5 +902,3 @@ extends: version: 1.0.0 - package: azure-mgmt-workloadssapvirtualinstance version: 1.0.0 - - diff --git a/eng/tools/azure-sdk-tools/ci_tools/parsing/parse_functions.py b/eng/tools/azure-sdk-tools/ci_tools/parsing/parse_functions.py index 0c5bb8b5ebab..31a3d8d323d4 100644 --- a/eng/tools/azure-sdk-tools/ci_tools/parsing/parse_functions.py +++ b/eng/tools/azure-sdk-tools/ci_tools/parsing/parse_functions.py @@ -351,12 +351,24 @@ def from_path(cls, parse_directory_or_file: str): def get_build_config(self) -> Optional[Dict[str, Any]]: return get_build_config(self.folder) + def get_conda_config(self) -> Optional[Dict[str, Any]]: + return get_conda_config(self.folder) + def get_config_setting(self, setting: str, default: Any = True) -> Any: return get_config_setting(self.folder, setting, default) def is_reporting_suppressed(self, setting: str) -> bool: return compare_string_to_glob_array(setting, self.get_config_setting("suppressed_skip_warnings", [])) + def is_stable_release(self) -> bool: + """ + Check if this package is a stable release version. + + :rtype: bool + :return: True if this is a stable release, False if beta + """ + return classify_release_type(self.version) == "stable" + def __str__(self): lines = [f"ParsedSetup from {self.folder}"] for attr in [ @@ -383,7 +395,7 @@ def __str__(self): def update_build_config(package_path: str, new_build_config: Dict[str, Any]) -> Dict[str, Any]: """ - Attempts to update a pyproject.toml's [tools.azure-sdk-tools] section with a new check configuration. + Attempts to update a pyproject.toml's [tool.azure-sdk-tools] section with a new check configuration. This function can only append or override existing check values. It cannot delete them. """ @@ -454,6 +466,27 @@ def get_build_config(package_path: str) -> Optional[Dict[str, Any]]: return {} +def get_conda_config(package_path: str) -> Optional[Dict[str, Any]]: + """ + Attempts to retrieve all values within [tools.azure-sdk-conda] section of a pyproject.toml. + """ + if os.path.isfile(package_path): + package_path = os.path.dirname(package_path) + + toml_file = os.path.join(package_path, "pyproject.toml") + + if os.path.exists(toml_file): + try: + with open(toml_file, "rb") as f: + toml_dict = toml.load(f) + if "tool" in toml_dict: + tool_configs = toml_dict["tool"] + if "azure-sdk-conda" in tool_configs: + return tool_configs["azure-sdk-conda"] + except: + return {} + + def get_ci_config(package_path: str) -> Optional[Dict[str, Any]]: """ Attempts to retrieve the parsed toml content of a CI.yml associated with this package. @@ -841,3 +874,16 @@ def compare_string_to_glob_array(string: str, glob_array: List[str]) -> bool: This function is used to easily compare a string to a set of glob strings, if it matches any of them, returns True. """ return any([fnmatch.fnmatch(string, glob) for glob in glob_array]) + + +def classify_release_type(version: str) -> str: + """ + Classify a package version as 'beta' or 'stable' based on version string patterns. + + :param str version: The version string to classify (e.g., "1.0.0", "2.1.0b1", "1.5.0a2") + :rtype: str + :return: Either "beta" or "stable" + """ + if "b" in version.lower(): + return "beta" + return "stable" diff --git a/sdk/communication/azure-communication-identity/pyproject.toml b/sdk/communication/azure-communication-identity/pyproject.toml index db898be6409d..fbc3cd0f05e1 100644 --- a/sdk/communication/azure-communication-identity/pyproject.toml +++ b/sdk/communication/azure-communication-identity/pyproject.toml @@ -1,9 +1,9 @@ [tool.azure-sdk-build] pyright = false -[tool.pytest.ini_options] -asyncio_default_fixture_loop_scope = "function" - [tool.azure-sdk-conda] -in_bundle = true +in_bundle = true bundle_name = "azure-communication" + +[tool.pytest.ini_options] +asyncio_default_fixture_loop_scope = "function" diff --git a/sdk/keyvault/azure-keyvault-keys/pyproject.toml b/sdk/keyvault/azure-keyvault-keys/pyproject.toml index 7caa00c7dd7c..e7036b8d69fa 100644 --- a/sdk/keyvault/azure-keyvault-keys/pyproject.toml +++ b/sdk/keyvault/azure-keyvault-keys/pyproject.toml @@ -47,6 +47,10 @@ pytyped = ["py.typed"] [tool.azure-sdk-build] pyright = false +[tool.azure-sdk-conda] +in_bundle = true +bundle_name = "azure-keyvault" + [tool.uv.sources] azure-core = { path = "../../core/azure-core" } azure-keyvault-nspkg = { path = "../../nspkg/azure-keyvault-nspkg" } @@ -63,7 +67,3 @@ dev = [ "parameterized>=0.7.3", "python-dateutil>=2.8.0", ] - -[tool.azure-sdk-conda] -in_bundle = true -bundle_name = "azure-keyvault"