Publish Python packages with Azure Pipelines

Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019

Using Azure Pipelines, developers can publish Python packages to Azure Artifacts feeds, public registries, or store them as pipeline artifacts. This article will guide you through how to:

  • Install the prerequisites
  • Connect to an Azure Artifacts feed
  • Publish Python packages to an Azure Artifacts feed


  • An Azure DevOps organization and a project. Create an organization or a project if you haven't already.

  • An Azure Artifacts feed. Create a feed if you don't have one already.

Authenticate with Azure Artifacts

To use twine for publishing your Python packages, you must first authenticate with your Azure Artifacts feed. The TwineAuthenticate task provides twine credentials to a PYPIRC_PATH environment variable. This variable is then used bytwine to facilitate the publishing of your packages directly from your pipeline.

- task: TwineAuthenticate@1
    artifactFeed: <PROJECT_NAME/FEED_NAME>     ## For an organization-scoped feed, artifactFeed: <FEED_NAME>


The credentials stored in the PYPIRC_PATH environment variable supersede those in your .ini and .conf files.

If you add multiple TwineAuthenticate tasks at different stages in your pipeline, each additional task execution will extend (not override) the existing PYPIRC_PATH environment variable.

Publish Python packages to an Azure Artifacts feed

- script: |
    pip install build
    pip install twine
  displayName: 'Install build and twine'

- script: |
    python -m build -w
  displayName: 'Python build'

- task: TwineAuthenticate@1
    artifactFeed: <PROJECT_NAME/FEED_NAME>
  displayName: 'Twine Authenticate'

- script: |
    python -m twine upload -r <FEED_NAME> --config-file $(PYPIRC_PATH) dist/*.whl
  displayName: 'Upload to feed'


To publish your packages to a feed using Azure Pipelines, both the Project Collection Build Service and your project's Build Service identities must have the Feed Publisher (Contributor) role assigned in your feed settings. See Manage permissions for details.