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

Implement private projects #1537

Open
2 tasks done
iamsauravsharma opened this issue Nov 4, 2019 · 9 comments
Open
2 tasks done

Implement private projects #1537

iamsauravsharma opened this issue Nov 4, 2019 · 9 comments
Labels
kind/feature Feature requests/implementations

Comments

@iamsauravsharma
Copy link

iamsauravsharma commented Nov 4, 2019

  • I have searched the issues of this repo and believe that this is not a duplicate.
  • I have searched the documentation and believe that my question is not covered.

Feature Request

Currently poetry doesn't support disabling publishing of package to remote repository. Add publish key similar to publish key present over cargo manifest for rust crates. publish key can have two types of value either bool or list of repository name. The publish field can be used to prevent a package from being published to a remote repository (like PYPI) by mistake, for instance to keep a package private in a company. If bool is present and is false then package cannot be published to any remote repository. Similarly if list of remote repository name is present then package can only be published to those remote repository.

[tool.poetry]
#....
publish=false
[tool.poetry]
#....
publish=["some-remote-repository-name"]
@iamsauravsharma iamsauravsharma added the kind/feature Feature requests/implementations label Nov 4, 2019
@515hikaru
Copy link
Contributor

I think this proposal is nice.

I set the following for packages that should not be made public.

[tool.poetry]
exclude = ["**/*"]

With this workaround, even if poetry publish is executed by mistake, the source code is not published. However, since poetry build includes pyproject.toml, setup.py, and PKG-INFO in the tar.gz file, such metadata may be disclosed.

This workaround is not good. I think you need an option to make it impossible to publish.

@alkasm
Copy link

alkasm commented Mar 16, 2020

Overall this is trivial to implement. The more important question here is the API / user experience. I'd be happy to push out a PR for this with some agreement from core devs on API. I have written down a host of options, there may be others as well.


Option 1: Borrow Rust Cargo's manifest publish

From Rust Cargo's publish field as in the OP. This follows an established standard from another packaging tool which uses TOML, and is easy to understand and document, but has disadvantages. It forces repetition of allowable repo names (leading to possible errors) and implicitly overrides default behavior. An empty list publish=[] would likely do the same thing as false leading to documentation confusion and multiple ways to do the same thing, and annoying that the publish option may have multiple types. The field name publish is intuitive for the boolean case, but unintuitive for the array.

Other similar options might be to provide an allowed-repos = [] array or disallowed-repos = [] array, or both:

[tool.poetry]
# ...
allowed-repos = ["test-pypi"]
disallowed-repos = ["pypi"]

Option 2: Override the PyPI URL

Currently, the default is hardcoded here. This means that poetry publish is different from poetry publish --repository pypi, where the latter will look up pypi in your registered repos. If the PyPI default could be stored inside the config, it could be looked up and overridden in config, by specifying a new URL. Thus you could simply set repositories.pypi.url = "" and disable PyPI (or any repo) uploads. Raised errors should probably catch that the value is an empty string to provide better context. This explicitly overrides the default behavior, which I prefer to option 1, although setting the URL to an empty string is not particularly great. The same wanted behavior could be achieved by setting it to any other URL that doesn't work.

poetry config repositories.pypi ""

Option 3: Override the PyPI table

The same as option 2, but instead of overriding the url field, just override the whole table with a blank table (that is, remove the url entirely). This is more explicit in intent, but less explicit in code, since repositories.pypi = {} doesn't read "set to an empty table instead of a table containing the url". Currently poetry config does not support this, since poetry config repositories.foo asdf sets the url field. Ideally, the url field would be explicit, but that would be a breaking change.

Unsure of how to handle this with poetry config.

Option 4: Add an optional publish field to the repositories.<name> table

We currently must specify repositories.<name>.url for each repo we want to be able to publish to, so it would make a lot of sense to add an optional boolean field publish (or a different name) to say whether this repo is allowed to be published to or not, defaulting to true to maintain backwards compatibility. Similar to options 2 & 3, this would likely require that PyPI is moved as a default config option which could be overridden. You would only need to override repositories.foo.publish = false, and not override the URL to some garbage value. This has the same poetry config problems as #3, but easier to special case this so that

poetry config repositories.foo https://foo.bar
poetry config repositories.foo.publish false

would create

[repositories.foo]
url = "https://foo.bar"
publish = false

Option 5: Provide a default-repo field

Currently PyPI is the default repo if unspecified, though a nice option may be to override that default so that poetry publish will publish to your default repo. This could be treated similar to option 1, although it would be either false or a single string (instead of an array). Alternatively could have a special string set aside to disallow publishing (probably empty string) in the same way an empty array could give the false-like behavior for option 1. This doesn't require repeating the allowed repos, so it's more attractive than option 1.

[tool.poetry]
default-repo = "test-pypi"

Personally I like option 4 the most; it is extensible, explicit, easy to document, and doesn't require overriding established fields.

The main drawback between almost all of these approaches is that publishing is disallowed by repo name instead of repo url. But if those things are grouped together (name, url and ability to publish) it doesn't seem like a huge issue. Of course the default behavior could be to check against URLs instead of name, and disallow if any one of the repos with the same URL has a false publish flag.

Other possible options and any input from the Poetry team would be great.

@sloev
Copy link

sloev commented Mar 16, 2020

its really dangerous i cant disable this cuz' 👇

if i have pypi configured globally then if i accidently run poetry publish in a repo it will publish my package to PYPI WTF!

please disable the publish command by default or let it recide in scripts, then we can also overwrite it if needed!!!

EDIT: i may have sounded very alarmist, but i still think its an issue

@utek
Copy link

utek commented Apr 9, 2020

I've implemented basic solution similar to @alkasm Option 5.
#2287 and python-poetry/poetry-core#19 with it you could prevent publishing by setting non existing repository. While you still could publish using -r option.

@alkasm
Copy link

alkasm commented Dec 15, 2020

Bumping this issue. Can we get any guidance or suggestions from the poetry team? Would be happy to work on this but again, I don't know the right UX vision for poetry's behavior here.

@graingert
Copy link
Contributor

you can add the "Private :: Do Not Upload" trove classifier pypi/warehouse#5440

@cadojo
Copy link

cadojo commented Jun 14, 2022

you can add the "Private :: Do Not Upload" trove classifier pypa/warehouse#5440

I really appreciate folks adding that, I love the new Private :: classifier logic.

Still, I think publish would still send bits to PyPi, right? If that's the case, then it would be great to have a feature to overwrite the default upload URLs so publish with no arguments doesn't go to PyPi at all.

@johnthagen
Copy link
Contributor

npm has a private field in their project configuration for this.

If you set "private": true in your package.json, then npm will refuse to publish it.

This is a way to prevent accidental publication of private repositories. If you would like to ensure that a given package is only ever published to a specific registry (for example, an internal registry), then use the publishConfig dictionary described below to override the registry config param at publish-time.

@neersighted neersighted changed the title Add support for disabling package publish Implement private projects Oct 9, 2022
@neersighted
Copy link
Member

tool.poetry.project.private = true makes sense to be -- it could hard-disable publishing and add the trove classifier. We could add a new field to tool.poetry.source along the lines of allow-private-publish or similar to whitelist certain sources, but I think that design might need more discussion as both the code and semantics need examining.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/feature Feature requests/implementations
Projects
None yet
Development

No branches or pull requests

9 participants