Search code examples
pythonazure-devopsazure-pipelinespypitwine

Store credentials for twine upload of artifacts


I'm building my python package using Azure DevOps pipeline and the generated artifact is then uploaded to a feed. Everything is working fine, however, I don't like the fact that I have a .pypirc file containing the credentials for the upload sitting in my repository.

Basically I'm uploading the artifact using:

- script: 'twine upload -r imglib --config-file .pypirc dist/imglib-*.tar.gz'

Is there another way to store the credentials, preferably not in a file that anyone could edit? I read something about storing the credentials in the key vault, but I don't see how change the pipeline (the yml file) to do this.

Thanks in advance.

EDIT:

Shaykis answere seems to be the right way, however, I'm not able to replace the placeholder in the .pypirc file using a bash command. All I get is three asterics when I print the content of .pypirc after replacement. For the replacement I use:

- script: 'sed -i "s/__password__/$PYPI_CRED_MAPPED/g" .pypirc'
  displayName: 'Setting PyPI credentials'
  env:
    PYPI_CRED_MAPPED: $(pypi_cred)

The content of .pypirs is (displayed during the build task using a bash cat .pypirc. Is there an easier way to debug the build prozess?):

[distutils]
Index-servers =
  pypi
  imglib

[imglib]
Repository = https://pkgs.dev.azure.com/XXX/_packaging/imglib/pypi/upload
username = imglib
password = ***

Does anyone know what is happening there?

EDIT 2:

I also tried to use $env:PYPI_CRED_MAPPED but in that case only the $env is replaced by nothing and all I'm left with is :PYPI_CRED_MAPPED. Also, I look at the docs and they use the variable directly (e.g. $PYPI_CRED_MAPPED, see bottom of page).

EDIT 3:

The three asterics are just a placeholder. It worked with $PYPI_CRED_MAPPED as mentioned in EDIT 2. The build process was failing because of another reason. I also tried it with the powershell command provided in the answer and it worked as well. So thank you for your help.


Solution

  • You can store the variable as a secret variable, in the .pypirc file put a placeholder and in the pipeline add a script that replace the placeholder with the variable.

    1) In the .yaml editor click on the 3 dots near the Save/Run button on the top right and then click "Variables".

    2) Add a new variable (pythonCred fore example) with the password and click on the lock icon to make it secret.

    3) Go to your .pypirc file and replace the password with __password__.

    4) In your pipeline add a PowerShell task to put the password:

    - powershell: |
        (Get-Content path/to/pypirc) -replace "__password__" , "$env:CredPython" | Set-Content -Path path/to/pypirc
      env: CredPython: $(pythonCred) # you must to map the variable because is a secret variable
    

    You can also use Azure Key Vault with this way, download the password from there in with Azure Key Vault task and replace update the .pypirc file.