Cannot make it work: Uploading to pypi from Gitlab pipelines

(Also asked in StackOverflow here)

I’m trying to upload a package to pypi using a Gitlab CI job, but I cannot make it work :confused: Anyone has a working example?

What I have tried so far in my .gitlab-ci.yaml (from my local machine all of them are working):

  1. Twine with a .pypirc file

    - echo "[distutils]" >> ~/.pypirc
    - echo "index-servers =" >> ~/.pypirc
    - echo "    pypi" >> ~/.pypirc
    - echo "" >> ~/.pypirc
    - echo "[pypi]" >> ~/.pypirc
    - 'echo "repository: https://upload.pypi.org/legacy/" >> ~/.pypirc'
    - 'echo "username: ${PYPI_USER}" >> ~/.pypirc'
    - 'echo "password: ${PYPI_PASSWORD}" >> ~/.pypirc'
    - python3 setup.py check sdist bdist  # This will fail if your creds are bad.
    - cat ~/.pypirc
    - twine upload dist/* --config-file ~/.pypirc
    
  2. Same as before but with $VARIABLE

    [...]
    - 'echo "username: $PYPI_USER" >> ~/.pypirc'
    - 'echo "password: $PYPI_PASSWORD" >> ~/.pypirc'
    [...]
    
  3. Two options before but using python setup.py ... upload

  4. twine upload dist/* -u $PYPI_USER -p $PYPI_PASSWORD

  5. twine upload dist/* wiht TWINE_USERNAME and TWINE_PASSWORD environment variables.

… and always get a 403 Client Error: Invalid or non-existent authentication information. I’m running out of options…

PD.- All variables I talk about are set via Settings > CI/CD > Secret variables (as protected, for the same branches I am running these jobs)

Did you fix this in the end?
Because i’m having the exact same problem.

Edit: nevermind, I accidentally switched password and username

I didnt’t try it again :frowning: how did you managed to make it?

Configuration below works but when you got “403 Invalid or non-existent authentication information.” than change password to avoid some special chars like $ and or %.

image: docker.km3net.de/base/python:3
pypi_deploy:
  stage: deploy
  cache: {}
  script:
    - pip install -U twine
    - python setup.py sdist
    - twine upload --verbose --repository-url https://test.pypi.org/legacy/ dist/*
  only:
    - master

Best regards.
Draqun

I was facing a problem saying that the username got EOF. After some discussion, the present setup it works fine is:

In Settings/CI-CD/Variables. Add TWINE_USERNAME and TWINE_PASSWORD in your secret variables. Mark them as protected and masked. Obs.: See the rules for the values of those variables, such as no dots, greater than 8 chars and no special as said before.

In Settings/Repository/Protected Tags mark tags to be protected and add the regex of your tags.Tks to jaraco@github.

In addition go to Settings/Repository/Push rules and mark Prevent committing secrets to Git and
Do not allow users to remove git tags with git push to create a more secure environment.

Other related links:

pypi_release:
  stage: deploy
  cache: {}
  script:
    - pip install -U twine
    - python setup.py sdist bdist_wheel
    - twine check dist/*
    # try upload in test platform before the oficial
    - twine upload --repository-url https://test.pypi.org/legacy/ dist/*
    - pip install --no-deps --index-url https://test.pypi.org/simple/ helpdev==$CI_COMMIT_TAG
    - pip uninstall helpdev -y
    # upload to oficial
    - twine upload --repository-url https://upload.pypi.org/legacy/ dist/*
    - pip install helpdev==$CI_COMMIT_TAG
    - helpdev --version
    - pip uninstall helpdev -y
  only:
    - tags