From 48acd6325dea85a8eeca8c1a19d1e6da923e58da Mon Sep 17 00:00:00 2001 From: "Michael Mainer (from Dev Box)" <8527305+MIchaelMainer@users.noreply.github.com> Date: Wed, 3 Jun 2026 10:52:41 -0700 Subject: [PATCH 1/6] feat(pipeline): add Azure Pipelines configuration for building and publishing Kiota Python packages to PyPI Retire the GitHub action used to publish this package. --- .azure-pipelines/cd-publish-python.yml | 337 +++++++++++++++++++++++++ .github/workflows/publish.yml | 75 ------ 2 files changed, 337 insertions(+), 75 deletions(-) create mode 100644 .azure-pipelines/cd-publish-python.yml delete mode 100644 .github/workflows/publish.yml diff --git a/.azure-pipelines/cd-publish-python.yml b/.azure-pipelines/cd-publish-python.yml new file mode 100644 index 0000000..cb0f9b0 --- /dev/null +++ b/.azure-pipelines/cd-publish-python.yml @@ -0,0 +1,337 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +# Build, package, and deploy Kiota Python packages to PyPI + +name: $(BuildDefinitionName)_$(SourceBranchName)_$(Date:yyyyMMdd)$(Rev:.r) + +trigger: + branches: + include: + - main + tags: + include: + - 'microsoft-kiota-abstractions-v*' + +pr: none + +variables: + pythonVersion: '3.14' + +resources: + repositories: + - repository: 1ESPipelineTemplates + type: git + name: 1ESPipelineTemplates/1ESPipelineTemplates + ref: refs/tags/release + +extends: + template: v1/1ES.Official.PipelineTemplate.yml@1ESPipelineTemplates + parameters: + pool: + name: Azure-Pipelines-1ESPT-ExDShared + vmImage: ubuntu-latest + stages: + + - stage: build + displayName: 'Build and Package Kiota Python Packages' + condition: or(contains(variables['Build.SourceBranch'], 'microsoft-kiota-abstractions-v'), eq(variables['Build.Reason'], 'Manual')) + jobs: + - job: build_python + displayName: 'Build, Test, and Package' + pool: + name: Azure-Pipelines-1ESPT-ExDShared + vmImage: ubuntu-latest + + steps: + - task: UsePythonVersion@0 + displayName: 'Install Python $(pythonVersion)' + inputs: + versionSpec: '$(pythonVersion)' + addToPath: true + + - script: python -m pip install --upgrade pip + displayName: 'Upgrade pip' + + - script: | + pip install poetry + pip install poetry-plugin-mono-repo-deps + displayName: 'Install Poetry and mono-repo-deps plugin' + + # Build and test kiota_abstractions + - script: poetry install + displayName: 'Install abstractions dependencies' + workingDirectory: '$(Build.SourcesDirectory)/packages/abstractions' + + - script: poetry run yapf -dr kiota_abstractions + displayName: 'Check code format - abstractions' + workingDirectory: '$(Build.SourcesDirectory)/packages/abstractions' + + - script: poetry run isort kiota_abstractions + displayName: 'Check import order - abstractions' + workingDirectory: '$(Build.SourcesDirectory)/packages/abstractions' + + - script: poetry run pylint kiota_abstractions --disable=W --rcfile=.pylintrc + displayName: 'Lint with Pylint - abstractions' + workingDirectory: '$(Build.SourcesDirectory)/packages/abstractions' + + - script: poetry run pytest + displayName: 'Run tests - abstractions' + workingDirectory: '$(Build.SourcesDirectory)/packages/abstractions' + + - script: poetry build + displayName: 'Build package - abstractions' + workingDirectory: '$(Build.SourcesDirectory)/packages/abstractions' + + # Build and test kiota_authentication_azure + - script: poetry install + displayName: 'Install authentication_azure dependencies' + workingDirectory: '$(Build.SourcesDirectory)/packages/authentication/azure' + + - script: poetry run yapf -dr kiota_authentication_azure + displayName: 'Check code format - authentication_azure' + workingDirectory: '$(Build.SourcesDirectory)/packages/authentication/azure' + + - script: poetry run isort kiota_authentication_azure + displayName: 'Check import order - authentication_azure' + workingDirectory: '$(Build.SourcesDirectory)/packages/authentication/azure' + + - script: poetry run pylint kiota_authentication_azure --disable=W --rcfile=.pylintrc + displayName: 'Lint with Pylint - authentication_azure' + workingDirectory: '$(Build.SourcesDirectory)/packages/authentication/azure' + + - script: poetry run pytest + displayName: 'Run tests - authentication_azure' + workingDirectory: '$(Build.SourcesDirectory)/packages/authentication/azure' + + - script: poetry build + displayName: 'Build package - authentication_azure' + workingDirectory: '$(Build.SourcesDirectory)/packages/authentication/azure' + + # Build and test kiota_http + - script: poetry install + displayName: 'Install http dependencies' + workingDirectory: '$(Build.SourcesDirectory)/packages/http/httpx' + + - script: poetry run yapf -dr kiota_http + displayName: 'Check code format - http' + workingDirectory: '$(Build.SourcesDirectory)/packages/http/httpx' + + - script: poetry run isort kiota_http + displayName: 'Check import order - http' + workingDirectory: '$(Build.SourcesDirectory)/packages/http/httpx' + + - script: poetry run pylint kiota_http --disable=W --rcfile=.pylintrc + displayName: 'Lint with Pylint - http' + workingDirectory: '$(Build.SourcesDirectory)/packages/http/httpx' + + - script: poetry run pytest + displayName: 'Run tests - http' + workingDirectory: '$(Build.SourcesDirectory)/packages/http/httpx' + + - script: poetry build + displayName: 'Build package - http' + workingDirectory: '$(Build.SourcesDirectory)/packages/http/httpx' + + # Build and test kiota_serialization_form + - script: poetry install + displayName: 'Install serialization_form dependencies' + workingDirectory: '$(Build.SourcesDirectory)/packages/serialization/form' + + - script: poetry run yapf -dr kiota_serialization_form + displayName: 'Check code format - serialization_form' + workingDirectory: '$(Build.SourcesDirectory)/packages/serialization/form' + + - script: poetry run isort kiota_serialization_form + displayName: 'Check import order - serialization_form' + workingDirectory: '$(Build.SourcesDirectory)/packages/serialization/form' + + - script: poetry run pylint kiota_serialization_form --disable=W --rcfile=.pylintrc + displayName: 'Lint with Pylint - serialization_form' + workingDirectory: '$(Build.SourcesDirectory)/packages/serialization/form' + + - script: poetry run pytest + displayName: 'Run tests - serialization_form' + workingDirectory: '$(Build.SourcesDirectory)/packages/serialization/form' + + - script: poetry build + displayName: 'Build package - serialization_form' + workingDirectory: '$(Build.SourcesDirectory)/packages/serialization/form' + + # Build and test kiota_serialization_json + - script: poetry install + displayName: 'Install serialization_json dependencies' + workingDirectory: '$(Build.SourcesDirectory)/packages/serialization/json' + + - script: poetry run yapf -dr kiota_serialization_json + displayName: 'Check code format - serialization_json' + workingDirectory: '$(Build.SourcesDirectory)/packages/serialization/json' + + - script: poetry run isort kiota_serialization_json + displayName: 'Check import order - serialization_json' + workingDirectory: '$(Build.SourcesDirectory)/packages/serialization/json' + + - script: poetry run pylint kiota_serialization_json --disable=W --rcfile=.pylintrc + displayName: 'Lint with Pylint - serialization_json' + workingDirectory: '$(Build.SourcesDirectory)/packages/serialization/json' + + - script: poetry run pytest + displayName: 'Run tests - serialization_json' + workingDirectory: '$(Build.SourcesDirectory)/packages/serialization/json' + + - script: poetry build + displayName: 'Build package - serialization_json' + workingDirectory: '$(Build.SourcesDirectory)/packages/serialization/json' + + # Build and test kiota_serialization_text + - script: poetry install + displayName: 'Install serialization_text dependencies' + workingDirectory: '$(Build.SourcesDirectory)/packages/serialization/text' + + - script: poetry run yapf -dr kiota_serialization_text + displayName: 'Check code format - serialization_text' + workingDirectory: '$(Build.SourcesDirectory)/packages/serialization/text' + + - script: poetry run isort kiota_serialization_text + displayName: 'Check import order - serialization_text' + workingDirectory: '$(Build.SourcesDirectory)/packages/serialization/text' + + - script: poetry run pylint kiota_serialization_text --disable=W --rcfile=.pylintrc + displayName: 'Lint with Pylint - serialization_text' + workingDirectory: '$(Build.SourcesDirectory)/packages/serialization/text' + + - script: poetry run pytest + displayName: 'Run tests - serialization_text' + workingDirectory: '$(Build.SourcesDirectory)/packages/serialization/text' + + - script: poetry build + displayName: 'Build package - serialization_text' + workingDirectory: '$(Build.SourcesDirectory)/packages/serialization/text' + + # Build and test kiota_serialization_multipart + - script: poetry install + displayName: 'Install serialization_multipart dependencies' + workingDirectory: '$(Build.SourcesDirectory)/packages/serialization/multipart' + + - script: poetry run yapf -dr kiota_serialization_multipart + displayName: 'Check code format - serialization_multipart' + workingDirectory: '$(Build.SourcesDirectory)/packages/serialization/multipart' + + - script: poetry run isort kiota_serialization_multipart + displayName: 'Check import order - serialization_multipart' + workingDirectory: '$(Build.SourcesDirectory)/packages/serialization/multipart' + + - script: poetry run pylint kiota_serialization_multipart --disable=W --rcfile=.pylintrc + displayName: 'Lint with Pylint - serialization_multipart' + workingDirectory: '$(Build.SourcesDirectory)/packages/serialization/multipart' + + - script: poetry run pytest + displayName: 'Run tests - serialization_multipart' + workingDirectory: '$(Build.SourcesDirectory)/packages/serialization/multipart' + + - script: poetry build + displayName: 'Build package - serialization_multipart' + workingDirectory: '$(Build.SourcesDirectory)/packages/serialization/multipart' + + # Build and test kiota_bundle + - script: poetry install + displayName: 'Install bundle dependencies' + workingDirectory: '$(Build.SourcesDirectory)/packages/bundle' + + - script: poetry run yapf -dr kiota_bundle + displayName: 'Check code format - bundle' + workingDirectory: '$(Build.SourcesDirectory)/packages/bundle' + + - script: poetry run isort kiota_bundle + displayName: 'Check import order - bundle' + workingDirectory: '$(Build.SourcesDirectory)/packages/bundle' + + - script: poetry run pylint kiota_bundle --disable=W --rcfile=.pylintrc + displayName: 'Lint with Pylint - bundle' + workingDirectory: '$(Build.SourcesDirectory)/packages/bundle' + + - script: poetry run pytest + displayName: 'Run tests - bundle' + workingDirectory: '$(Build.SourcesDirectory)/packages/bundle' + + - script: poetry build + displayName: 'Build package - bundle' + workingDirectory: '$(Build.SourcesDirectory)/packages/bundle' + + # Copy all built packages to staging + - task: CopyFiles@2 + displayName: 'Copy all package artifacts to staging' + inputs: + CleanTargetFolder: true + sourceFolder: '$(Build.SourcesDirectory)' + targetFolder: '$(Build.ArtifactStagingDirectory)/python/kiota_packages' + Contents: | + packages/abstractions/dist/*.tar.gz + packages/abstractions/dist/*.whl + packages/authentication/azure/dist/*.tar.gz + packages/authentication/azure/dist/*.whl + packages/http/httpx/dist/*.tar.gz + packages/http/httpx/dist/*.whl + packages/serialization/form/dist/*.tar.gz + packages/serialization/form/dist/*.whl + packages/serialization/json/dist/*.tar.gz + packages/serialization/json/dist/*.whl + packages/serialization/text/dist/*.tar.gz + packages/serialization/text/dist/*.whl + packages/serialization/multipart/dist/*.tar.gz + packages/serialization/multipart/dist/*.whl + packages/bundle/dist/*.tar.gz + packages/bundle/dist/*.whl + flattenFolders: true + + templateContext: + outputs: + - output: pipelineArtifact + displayName: 'Stage Kiota Python package artifacts' + artifactName: pypi_kiota_packages + targetPath: '$(Build.ArtifactStagingDirectory)/python/kiota_packages' + condition: or(contains(variables['Build.SourceBranch'], 'microsoft-kiota-abstractions-v'), eq(variables['Build.Reason'], 'Manual')) + + - stage: deploy + displayName: 'Publish Kiota Python Packages to PyPI' + dependsOn: build + condition: or(and(contains(variables['Build.SourceBranch'], 'microsoft-kiota-abstractions-v'), succeeded()), eq(variables['Build.Reason'], 'Manual')) + jobs: + - deployment: publish_python_packages + displayName: 'Publish Kiota Python Packages' + environment: kiota-python-prod + pool: + name: Azure-Pipelines-1ESPT-ExDShared + image: ubuntu-latest + os: linux + + templateContext: + type: releaseJob + isProduction: true + inputs: + - input: pipelineArtifact + artifactName: pypi_kiota_packages + targetPath: '$(Build.ArtifactStagingDirectory)/python' + strategy: + runOnce: + deploy: + steps: + - task: EsrpRelease@9 + displayName: 'Publish Kiota Python packages via ESRP Release' + inputs: + connectedservicename: "Federated DevX ESRP Managed Identity Connection" + usemanagedidentity: false + keyvaultname: 'akv-prod-eastus' + authcertname: 'ReferenceLibraryPrivateCert' + signcertname: 'ReferencePackagePublisherCertificate' + clientid: '65035b7f-7357-4f29-bf25-c5ee5c3949f8' + intent: 'PackageDistribution' + contenttype: 'PYPI' + contentsource: 'Folder' + folderlocation: '$(Build.ArtifactStagingDirectory)/python' + waitforreleasecompletion: true + owners: 'mmainer@microsoft.com,gavinbarron@microsoft.com' + approvers: 'mmainer@microsoft.com,christiano@microsoft.com,gavinbarron@microsoft.com,lramosvea@microsoft.com' + serviceendpointurl: 'https://api.esrp.microsoft.com' + mainpublisher: 'ESRPRELPACMAN' + domaintenantid: 'cdc5aeea-15c5-4db6-b079-fcadd2505dc2' diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml deleted file mode 100644 index 09c5c15..0000000 --- a/.github/workflows/publish.yml +++ /dev/null @@ -1,75 +0,0 @@ -name: Publish package to PyPI - -on: - push: - tags: - - "microsoft-kiota-abstractions-v*" # Push events to matching microsoft-kiota-abstractions-v*, i.e. microsoft-kiota-abstractions-v1.0, microsoft-kiota-abstractions-v20.15.10 - # All packages are ideally released together so we can use the same tag for all packages - -permissions: - contents: write - -jobs: - build: - uses: ./.github/workflows/build.yml - - publish: - name: Publish distribution to PyPI - runs-on: ubuntu-latest - if: startsWith(github.ref, 'refs/tags/microsoft-kiota-abstractions-v') - environment: pypi_prod - needs: [build] - env: - POETRY_PYPI_TOKEN_PYPI: ${{ secrets.PYPI_API_TOKEN }} - steps: - - name: Checkout code - uses: actions/checkout@v6 - - name: Set up Python - uses: actions/setup-python@v6 - with: - python-version: "3.14" - - name: Install poetry and mono-repo-deps plugin - run: | - python -m pip install --upgrade poetry - python -m pip install --upgrade poetry-plugin-mono-repo-deps - - name: Publish kiota_abstractions to PyPI - run: | - poetry install - poetry publish --build - working-directory: "./packages/abstractions" - - name: Publish kiota_authentication_azure to PyPI - run: | - poetry install - poetry publish --build - working-directory: "./packages/authentication/azure" - - name: Publish kiota_http to PyPI - run: | - poetry install - poetry publish --build - working-directory: "./packages/http/httpx" - - name: Publish kiota_serialization_form to PyPI - run: | - poetry install - poetry publish --build - working-directory: "./packages/serialization/form" - - name: Publish kiota_serialization_json to PyPI - run: | - poetry install - poetry publish --build - working-directory: "./packages/serialization/json" - - name: Publish kiota_serialization_text to PyPI - run: | - poetry install - poetry publish --build - working-directory: "./packages/serialization/text" - - name: Publish kiota_serialization_multipart to PyPI - run: | - poetry install - poetry publish --build - working-directory: "./packages/serialization/multipart" - - name: Publish kiota_bundle to PyPI - run: | - poetry install - poetry publish --build - working-directory: "./packages/bundle" - \ No newline at end of file From dc350f59fd970431a9d015041c08e1054f73eab9 Mon Sep 17 00:00:00 2001 From: "Michael Mainer (from Dev Box)" <8527305+MIchaelMainer@users.noreply.github.com> Date: Wed, 3 Jun 2026 13:36:02 -0700 Subject: [PATCH 2/6] chore(pipeline): add sdl pool info --- .azure-pipelines/cd-publish-python.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.azure-pipelines/cd-publish-python.yml b/.azure-pipelines/cd-publish-python.yml index cb0f9b0..4395ed7 100644 --- a/.azure-pipelines/cd-publish-python.yml +++ b/.azure-pipelines/cd-publish-python.yml @@ -31,6 +31,12 @@ extends: pool: name: Azure-Pipelines-1ESPT-ExDShared vmImage: ubuntu-latest + os: linux + sdl: + sourceAnalysisPool: + name: Azure-Pipelines-1ESPT-ExDShared + image: windows-2022 + os: windows stages: - stage: build @@ -299,7 +305,7 @@ extends: jobs: - deployment: publish_python_packages displayName: 'Publish Kiota Python Packages' - environment: kiota-python-prod + environment: pypi_prod pool: name: Azure-Pipelines-1ESPT-ExDShared image: ubuntu-latest From 39f77e426cb28a87b5926a548067f92743ab35e4 Mon Sep 17 00:00:00 2001 From: "Michael Mainer (from Dev Box)" <8527305+MIchaelMainer@users.noreply.github.com> Date: Wed, 3 Jun 2026 14:52:22 -0700 Subject: [PATCH 3/6] chore: remove os setting --- .azure-pipelines/cd-publish-python.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.azure-pipelines/cd-publish-python.yml b/.azure-pipelines/cd-publish-python.yml index 4395ed7..e33d757 100644 --- a/.azure-pipelines/cd-publish-python.yml +++ b/.azure-pipelines/cd-publish-python.yml @@ -31,7 +31,6 @@ extends: pool: name: Azure-Pipelines-1ESPT-ExDShared vmImage: ubuntu-latest - os: linux sdl: sourceAnalysisPool: name: Azure-Pipelines-1ESPT-ExDShared From 4d9ac8cd3fdddc1874a2b64acb8372a790060a13 Mon Sep 17 00:00:00 2001 From: "Michael Mainer (from Dev Box)" <8527305+MIchaelMainer@users.noreply.github.com> Date: Wed, 3 Jun 2026 15:17:33 -0700 Subject: [PATCH 4/6] fix(pipeline): update Azure Pipelines configuration to use 'image' instead of 'vmImage' and specify OS --- .azure-pipelines/cd-publish-python.yml | 6 ++++-- .vscode/settings.json | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.azure-pipelines/cd-publish-python.yml b/.azure-pipelines/cd-publish-python.yml index e33d757..4cf1aa1 100644 --- a/.azure-pipelines/cd-publish-python.yml +++ b/.azure-pipelines/cd-publish-python.yml @@ -30,7 +30,8 @@ extends: parameters: pool: name: Azure-Pipelines-1ESPT-ExDShared - vmImage: ubuntu-latest + image: ubuntu-latest + os: linux sdl: sourceAnalysisPool: name: Azure-Pipelines-1ESPT-ExDShared @@ -46,7 +47,8 @@ extends: displayName: 'Build, Test, and Package' pool: name: Azure-Pipelines-1ESPT-ExDShared - vmImage: ubuntu-latest + image: ubuntu-latest + os: linux steps: - task: UsePythonVersion@0 diff --git a/.vscode/settings.json b/.vscode/settings.json index 790145e..7d688dd 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -16,5 +16,6 @@ "--rootdir=${workspaceFolder}" ], "python.testing.unittestEnabled": false, - "python.testing.pytestEnabled": false, // Disable pytest (does not work with poetry yet) + "python.testing.pytestEnabled": false, + "azure-pipelines.1ESPipelineTemplatesSchemaFile": true, // Disable pytest (does not work with poetry yet) } \ No newline at end of file From 3dd59a43b5bb026deaf5947e877a7b13e4f6d496 Mon Sep 17 00:00:00 2001 From: "Michael Mainer (from Dev Box)" <8527305+MIchaelMainer@users.noreply.github.com> Date: Wed, 3 Jun 2026 15:31:50 -0700 Subject: [PATCH 5/6] feat(pipeline): add pip authentication step for Azure Artifacts in CI pipeline --- .azure-pipelines/cd-publish-python.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.azure-pipelines/cd-publish-python.yml b/.azure-pipelines/cd-publish-python.yml index 4cf1aa1..d836d6f 100644 --- a/.azure-pipelines/cd-publish-python.yml +++ b/.azure-pipelines/cd-publish-python.yml @@ -60,6 +60,11 @@ extends: - script: python -m pip install --upgrade pip displayName: 'Upgrade pip' + - task: PipAuthenticate@1 + displayName: "Authenticate pip to Azure Artifacts" + inputs: + artifactFeeds: "$(System.TeamProject)/msgraph-python-dev" + - script: | pip install poetry pip install poetry-plugin-mono-repo-deps From af456af8f62b19f27df062ae3b277b85c5004b23 Mon Sep 17 00:00:00 2001 From: Michael Mainer <8527305+MIchaelMainer@users.noreply.github.com> Date: Wed, 3 Jun 2026 15:37:52 -0700 Subject: [PATCH 6/6] chore: remove trigger on main Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .azure-pipelines/cd-publish-python.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.azure-pipelines/cd-publish-python.yml b/.azure-pipelines/cd-publish-python.yml index d836d6f..c27139b 100644 --- a/.azure-pipelines/cd-publish-python.yml +++ b/.azure-pipelines/cd-publish-python.yml @@ -6,13 +6,9 @@ name: $(BuildDefinitionName)_$(SourceBranchName)_$(Date:yyyyMMdd)$(Rev:.r) trigger: - branches: - include: - - main tags: include: - 'microsoft-kiota-abstractions-v*' - pr: none variables: