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

Add uv publish: Basic upload with username/password or keyring #2

Closed
wants to merge 19 commits into from

Conversation

konstin
Copy link
Owner

@konstin konstin commented Sep 19, 2024

The uv publish command allows uploading wheels and source distributions to PyPI or another registry. We support username/password auth, token auth and (follow-up) trusted publishing from GitHub Actions. Be default we upload files from dist/*, the output directory from uv build.

This is intended to support three different workflow, ordered by relevance:

  1. Publishing a pure Python package from CI
  • Call uv build
  • Clear the venv, install the wheel, run a smoke test
  • Clear the venv, install the source distribution, run a smoke test
  • Call uv publish
  1. Publishing a native module package from CI
  • In one job, call uv build, clear the venv, install the source distribution, run a smoke test, upload the source distribution as artifact
  • For each target, run a job, call uv build --wheel, clear the venv, install the wheel run a smoke test, upload the wheel as artifact
  • In a final job, download all artifacts to dist/* and run uv publish
  1. Publishing from a developer machine
  • Call uv build
  • Do a manual test routine
  • Call uv publish

Since we intend for smoke tests, there is no combined build-and-publish command.

What works:

  • Basic upload to pypi with token or username/password (username must be __token__, but it uses the same HTTP headers)
  • Keyring integration. If you use scoped tokens, you need use url-string hacks such as Not obvious how to use multiple project API tokens with keyring pypa/twine#565 (comment) to differentiate the tokens, a problem we share with twine.
  • Error messages
  • Testing on CI. Every time something in the upload crate or its test script changes, we upload a new version of dummy packages to testpypi

Next PRs:

  • Trusted publishing from GitHub actions with OIDC, and testing for it.

What's missing:

  • Other registries?

charliermarsh and others added 19 commits September 18, 2024 10:01
…sh#7500)

## Summary

See: astral-sh#7485. The test was using `uv
pip sync` which doesn't require fetching metadata, and the failure was
in fetching metadata.
This changes the structure of the hints generator in the resolver when
encountering solution errors, so that it re-uses a single output buffer
owned by the caller.
It avoids repeated allocations of a temporary buffer within each
recursive function call.
## Summary

This adds about 50 KB to the binary:

```
❯ du ./target/release/socks
44736	./target/release/socks

❯ du ./target/release/uv
44632	./target/release/uv
```

So need some input on whether it's worth supporting.

Closes astral-sh#7484.
More whack-a-mole following in the tradition of astral-sh#7012.
Recently, rkyv 0.8 was released. Its API is a fair bit simpler now for
higher level uses (like for us in `uv`) and results in us being able to
delete a fair bit of code. This also removes our last dependency on `syn
1.0`, and thus drops that dependency.

Performance (via testing on the `transformers` example) seems to remain
about the same, which is what was expected:

```
$ hyperfine -w5 -r100 'uv lock' 'uv-ag-rkyv-update lock'
Benchmark 1: uv lock
  Time (mean ± σ):      55.6 ms ±   6.4 ms    [User: 30.4 ms, System: 35.1 ms]
  Range (min … max):    43.0 ms …  73.1 ms    100 runs

Benchmark 2: uv-ag-rkyv-update lock
  Time (mean ± σ):      56.5 ms ±   7.2 ms    [User: 30.5 ms, System: 36.3 ms]
  Range (min … max):    39.1 ms …  71.5 ms    100 runs

Summary
  uv lock ran
    1.02 ± 0.18 times faster than uv-ag-rkyv-update lock
```

Closes astral-sh#7415
…7523)

This stands out alongside other messaging which uses the longer spelling
"virtual environment"
As we support more complex Python discovery behaviors such as:

- astral-sh#7431 
- astral-sh#7335 
- astral-sh#7300 

`Any` is no longer accurate, we actually are looking for a reasonable
default Python version to use which may exclude the first one we find.
Separately, we need the idea of `Any` to improve behavior when listing
versions (e.g., astral-sh#7286) where we do actually want to match _any_ Python
version. As a first step, we'll rename `Any` to `Default`. Then, we'll
introduce a new `Any` that actually behaves as we'd expect.
…-sh#7530)

I think it's best practice to use a placeholder when we transform
something, and astral-sh#7522 is having snapshot issues because this filter
conflicts with `with_filtered_virtualenv_bin`
…al-sh#7517)

Follow-up to astral-sh#7514 and astral-sh#7526 adding
the `Any` variants again with slightly different semantics (i.e., they
allow pre-releases)

We'll be able to use this in astral-sh#7508
to avoid querying a bunch of alternative interpreters unnecessarily in
the non-list case.
When sending an upload request, we use HTTP formdata requests, which can't be cloned (seanmonstar/reqwest#2416, plus a limitation that formdata bodies are always internally streaming), but also know that we need to always have credentials.

The authentication middleware by default tries to clone the request and send an authenticated request first. By introducing an `only_authenticated` setting, we can skip this behaviour for publishing.

Split out from astral-sh#7475
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants