Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

POETRY_PYPI_TOKEN_PYPI KeyRingError in GitHub Actions #5189

Closed
3 tasks done
davegaeddert opened this issue Feb 11, 2022 · 6 comments · Fixed by #5911
Closed
3 tasks done

POETRY_PYPI_TOKEN_PYPI KeyRingError in GitHub Actions #5189

davegaeddert opened this issue Feb 11, 2022 · 6 comments · Fixed by #5911
Labels
kind/bug Something isn't working as expected

Comments

@davegaeddert
Copy link
Contributor

  • I am on the latest Poetry version.
  • I have searched the issues of this repo and believe that this is not a duplicate.
  • If an exception occurs when executing a command, I executed it again in debug mode (-vvv option).

Issue

From what I can tell, the latest release isn't picking up the POETRY_PYPI_TOKEN_PYPI environment variable like it did before? I can't find anything else that would have changed from how I had it working previously, other than a new Poetry release.

Here's a link to a GitHub Action run I have testing it with poetry publish —dry-run:
https://github.com/dropseed/workhorse/runs/5158999743?check_suite_focus=true#step:3:176

  Stack trace:

  7  ~/.local/lib/python3.8/site-packages/clikit/console_application.py:131 in run
      129│             parsed_args = resolved_command.args
      130│ 
    → 131│             status_code = command.handle(parsed_args, io)
      132│         except KeyboardInterrupt:
      133│             status_code = 1

  6  ~/.local/lib/python3.8/site-packages/clikit/api/command/command.py:120 in handle
      118│     def handle(self, args, io):  # type: (Args, IO) -> int
      119│         try:
    → 120│             status_code = self._do_handle(args, io)
      121│         except KeyboardInterrupt:
      122│             if io.is_debug():

  5  ~/.local/lib/python3.8/site-packages/clikit/api/command/command.py:171 in _do_handle
      169│         handler_method = self._config.handler_method
      170│ 
    → 171│         return getattr(handler, handler_method)(args, io, self)
      172│ 
      173│     def __repr__(self):  # type: () -> str

  4  ~/.local/lib/python3.8/site-packages/cleo/commands/command.py:92 in wrap_handle
       90│         self._command = command
       91│ 
    →  92│         return self.handle()
       93│ 
       94│     def handle(self):  # type: () -> Optional[int]

  3  ~/.local/lib/python3.8/site-packages/poetry/console/commands/publish.py:77 in handle
      75│         )
      76│ 
    → 77│         publisher.publish(
      78│             self.option("repository"),
      79│             self.option("username"),

  2  ~/.local/lib/python3.8/site-packages/poetry/publishing/publisher.py:54 in publish
      52│         if not (username and password):
      53│             # Check if we have a token first
    → 54│             token = self._password_manager.get_pypi_token(repository_name)
      55│             if token:
      56│                 logger.debug("Found an API token for {}.".format(repository_name))

  1  ~/.local/lib/python3.8/site-packages/poetry/utils/password_manager.py:145 in get_pypi_token
      143│             return self._config.get("pypi-token.{}".format(name))
      144│ 
    → 145│         return self.keyring.get_password(name, "__token__")
      146│ 
      147│     def delete_pypi_token(self, name):

  KeyRingError

  Unable to retrieve the password for poetry-repository-pypi from the key ring

  at ~/.local/lib/python3.8/site-packages/poetry/utils/password_manager.py:39 in get_password
       35│ 
       36│         try:
       37│             return keyring.get_password(name, username)
       38│         except (RuntimeError, keyring.errors.KeyringError):
    →  39│             raise KeyRingError(
       40│                 "Unable to retrieve the password for {} from the key ring".format(name)
       41│             )
       42│ 
       43│     def set_password(self, name, username, password):

Here's the workflow: https://github.com/dropseed/workhorse/blob/69a7e144960c9ef961dbdd172b4115095564a44a/.github/workflows/poetry-test.yml

on: push

jobs:
  sync:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - env: 
        POETRY_PYPI_TOKEN_PYPI: ${{ secrets.DROPSEED_PYPI_TOKEN }}
      run: |
        pip3 install -U pip poetry
        echo "Token length: ${#POETRY_PYPI_TOKEN_PYPI}"
        poetry publish --build --dry-run -vvv

Thanks for your help and maintaining poetry! Let me know if there's anything else I can do to help on this.

@davegaeddert davegaeddert added kind/bug Something isn't working as expected status/triage This issue needs to be triaged labels Feb 11, 2022
@davegaeddert
Copy link
Contributor Author

davegaeddert commented Feb 11, 2022

I will try to do a little more digging, but just a quick update that I think I narrowed it down to keyring>=23.2.0 (which is now allowed in 1.1.3)...
https://github.com/dropseed/workhorse/actions/runs/1830501491
CleanShot 2022-02-11 at 10 56 07

@davegaeddert
Copy link
Contributor Author

I ended up opening this issue: jaraco/keyring#561

Not sure if that's the right idea or if other solutions come to mind for anyone.

@abn
Copy link
Member

abn commented May 12, 2022

I suspect the issue is the logic here.

def get_pypi_token(self, name: str) -> str | None:
if not self.keyring.is_available():
token: str | None = self._config.get(f"pypi-token.{name}")
return token
return self.keyring.get_password(name, "__token__")

If keyring is available env vars are not checked when uploading.

@abn abn added Good First Issue and removed status/triage This issue needs to be triaged labels May 12, 2022
@John15321
Copy link
Contributor

I suspect the issue is the logic here.

def get_pypi_token(self, name: str) -> str | None:
if not self.keyring.is_available():
token: str | None = self._config.get(f"pypi-token.{name}")
return token
return self.keyring.get_password(name, "__token__")

If keyring is available env vars are not checked when uploading.

But why would keyring be available if later we get an error when trying to get it?

@John15321
Copy link
Contributor

John15321 commented Jun 19, 2022

Wait why would we assign the value of True for the _is_available just upon the creation of the PoetryKeyrying when it is actually determined if it's available when we actually call the get method?

def get_password(self, name: str, username: str) -> str | None:
if not self.is_available():
return None
import keyring
import keyring.errors
name = self.get_entry_name(name)
try:
return keyring.get_password(name, username)
except (RuntimeError, keyring.errors.KeyringError):
raise KeyRingError(
f"Unable to retrieve the password for {name} from the key ring"
)

Secrus added a commit that referenced this issue Aug 22, 2022
* add checking for env variable in pypi token getter

* add unit tests for env pypi token

* add checking for env variable in pypi token getter

* add unit tests for env pypi token

* add info to the changelog

* refactor the structure

* fix unit tests

* undo changelog addition

* change docstring format to sphinx

* delete uncrsy unit test

* Delete unscry funtion call

Co-authored-by: Bjorn Neergaard <bjorn@neersighted.com>

* Update src/poetry/utils/password_manager.py

Co-authored-by: Bartosz Sokorski <b.sokorski@gmail.com>

* fix unit tests

* lol

* fix type hints

Co-authored-by: Bjorn Neergaard <bjorn@neersighted.com>
Co-authored-by: Bartosz Sokorski <b.sokorski@gmail.com>
Copy link

github-actions bot commented Mar 1, 2024

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 1, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
kind/bug Something isn't working as expected
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants