6

I am trying to set up Azure Devops to publish to a PyPI feed with Poetry.

I know about Twine authentication and storing credentials to an Azure Key Vault. But is there any more straightforward method? Something like this:

- script: |
    source .venv/bin/activate
    poetry build
  displayName: Build wheel
- script: |
    source .venv/bin/activate
    poetry publish -u USER -p PASS
  displayName: Publish wheel
Géry Ogam
  • 6,336
  • 4
  • 38
  • 67
Dan Yeaw
  • 741
  • 8
  • 16

3 Answers3

8

Yes. In the Azure DevOps web interface:

  1. Create a new PyPI feed (Artifacts > New feed > Create).
  2. Create PyPI credentials (Connect to feed > Python > Generate Python credentials).
  3. Create secret pipeline variables named username and password and valued with the PyPI credentials (Pipelines > Edit > Variables > New variable > Keep this value secret > OK).
  4. Update the contents of the azure-pipelines.yml CI file with this:
trigger:
- master

pool:
  vmImage: ubuntu-latest

steps:
- task: UsePythonVersion@0
  inputs:
    versionSpec: 3.7
  displayName: Install Python
- script: |
    python -m pip install -U pip
    pip install poetry
    poetry install
  displayName: Install software
- script: |
    poetry run python -m unittest discover tests/ -v
  displayName: Test software
- script: |
    poetry build
  displayName: Package software
- script: |
    poetry config repositories.azure https://pkgs.dev.azure.com/{your organization}/_packaging/{your feed}/pypi/upload
    poetry config http-basic.azure $(username) $(password)
    poetry publish -r azure
    exit 0
  displayName: Publish software
Géry Ogam
  • 6,336
  • 4
  • 38
  • 67
  • Does this mean I would post my password or a personal authentication token in plain text in my .azure-pipelines.yml? If not, I am not sure I understand what would go in the poetry http-basic config line you mentioned. – Dan Yeaw Sep 20 '19 at 01:29
  • @DanYeaw Yes, here you write your credentials in plaintext in the `azure-pipelines.yml` (you asked for a straightforward solution). – Géry Ogam Sep 20 '19 at 09:32
  • Yes, straightforward is good, but we also need something that won't expose our credentials to everyone – Dan Yeaw Sep 22 '19 at 12:14
  • 1
    @DanYeaw I have updated the answer for setting PyPI credentials without exposing them to the version control system, using Azure Pipelines _secret variables_, which is the recommended practice. I hope this helps. – Géry Ogam Sep 23 '19 at 08:58
5

How about building with poetry and publishing with twine, so we can take advantage of Azure's own TwineAuthenticate:

steps:
  - task: UsePythonVersion@0
    inputs:
      versionSpec: '$(python.version)'
    displayName: 'Use Python $(python.version)'

  - script: |
      python -m pip install --upgrade pip
      pip install poetry
      pip install twine
      poetry install --no-dev
    displayName: 'Install dependencies'

  - script: |
      poetry build
    displayName: 'Build package'

  - task: TwineAuthenticate@1
    inputs:
      artifactFeed: 'repo-name/feed-name'

  - script: |
      twine upload -r repo-name --config-file $(PYPIRC_PATH) dist/*.whl
    displayName: Upload package to Azure Artifact
Lucia
  • 13,033
  • 6
  • 44
  • 50
2

You may want to use $(System.AccessToken) variable:

- task: Bash@3
    inputs:
      targetType: 'inline'
      script: |
        poetry config repositories.myazurepypi https://myorg.pkgs.visualstudio.com/123415462134546/_packaging/lcp-tools/pypi/upload/
        poetry publish -r myazurepypi -u a -p $(System.AccessToken)
mijhael3000
  • 113
  • 1
  • 7
  • For anyone wondering, the username doesn't matter when using publishing to artifacts either using a PAT or System.AccessToken, but it can't be empty. – RubberDuck May 10 '22 at 12:10