📝🎨 Put OIDC on pedestal @ README

This patch makes sure that the new users would go for the secretless
publishing when integrating the action, from the beginning.
This commit is contained in:
Sviatoslav Sydorenko 2023-04-24 07:26:17 +02:00
parent 7a1a355fb5
commit f47b34707f
No known key found for this signature in database
GPG Key ID: 9345E8FEA89CA455
1 changed files with 37 additions and 46 deletions

View File

@ -23,48 +23,6 @@ tag, or a full Git commit SHA.
## Usage ## Usage
To use the action add the following step to your workflow file (e.g.
`.github/workflows/main.yml`)
```yml
- name: Publish a Python distribution to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
password: ${{ secrets.PYPI_API_TOKEN }}
```
> **Pro tip**: instead of using branch pointers, like `unstable/v1`, pin
versions of Actions that you use to tagged versions or sha1 commit identifiers.
This will make your workflows more secure and better reproducible, saving you
from sudden and unpleasant surprises.
A common use case is to upload packages only on a tagged commit, to do so add a
filter to the step:
```yml
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags')
```
So the full step would look like:
```yml
- name: Publish package
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags')
uses: pypa/gh-action-pypi-publish@release/v1
with:
password: ${{ secrets.PYPI_API_TOKEN }}
```
The example above uses the new [API token][PyPI API token] feature of
PyPI, which is recommended to restrict the access the action has.
The secret used in `${{ secrets.PYPI_API_TOKEN }}` needs to be created on the
settings page of your project on GitHub. See [Creating & using secrets].
### Trusted publishing ### Trusted publishing
> **NOTE**: Trusted publishing is sometimes referred to by its > **NOTE**: Trusted publishing is sometimes referred to by its
@ -72,6 +30,10 @@ settings page of your project on GitHub. See [Creating & using secrets].
> If you see references to "OIDC publishing" in the context of PyPI, > If you see references to "OIDC publishing" in the context of PyPI,
> this is what they're referring to. > this is what they're referring to.
This example jumps right into the current best practice. If you want to
go for less secure scoped PyPI API tokens, check out [how to specify
username and password].
This action supports PyPI's [trusted publishing] This action supports PyPI's [trusted publishing]
implementation, which allows authentication to PyPI without a manually implementation, which allows authentication to PyPI without a manually
configured API token or username/password combination. To perform configured API token or username/password combination. To perform
@ -82,6 +44,7 @@ To enter the trusted publishing flow, configure this action's job with the
`id-token: write` permission and **without** an explicit username or password: `id-token: write` permission and **without** an explicit username or password:
```yaml ```yaml
# .github/workflows/ci-cd.yml
jobs: jobs:
pypi-publish: pypi-publish:
name: Upload release to PyPI name: Upload release to PyPI
@ -98,6 +61,11 @@ jobs:
uses: pypa/gh-action-pypi-publish@release/v1 uses: pypa/gh-action-pypi-publish@release/v1
``` ```
> **Pro tip**: instead of using branch pointers, like `unstable/v1`, pin
versions of Actions that you use to tagged versions or sha1 commit identifiers.
This will make your workflows more secure and better reproducible, saving you
from sudden and unpleasant surprises.
Other indices that support trusted publishing can also be used, like TestPyPI: Other indices that support trusted publishing can also be used, like TestPyPI:
```yaml ```yaml
@ -114,6 +82,13 @@ _(don't forget to update the environment name to `testpypi` or similar!)_
> or test environment won't be able to elevate privileges while flying under > or test environment won't be able to elevate privileges while flying under
> the radar. > the radar.
A common use case is to upload packages only on a tagged commit, to do so add a
filter to the job:
```yml
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags')
```
## Non-goals ## Non-goals
@ -149,7 +124,7 @@ by putting them into the `dist/` folder prior to running this Action.
For best results, figure out what kind of workflow fits your For best results, figure out what kind of workflow fits your
project's specific needs. project's specific needs.
For example, you could implement a parallel workflow that For example, you could implement a parallel job that
pushes every commit to TestPyPI or your own index server, pushes every commit to TestPyPI or your own index server,
like `devpi`. For this, you'd need to (1) specify a custom like `devpi`. For this, you'd need to (1) specify a custom
`repository-url` value and (2) generate a unique version `repository-url` value and (2) generate a unique version
@ -158,8 +133,11 @@ The latter is possible if you use `setuptools_scm` package but
you could also invent your own solution based on the distance you could also invent your own solution based on the distance
to the latest tagged commit. to the latest tagged commit.
You'll need to create another token for a separate host and then You'll need to create another token for a separate host and then [save it as a
[save it as a GitHub repo secret][Creating & using secrets]. GitHub repo secret][Creating & using secrets] under an environment used in
your job. Though, passing a password would disable the secretless [trusted
publishing] so it's better to configure it instead, when publishing to TestPyPI
and not something custom.
The action invocation in this case would look like: The action invocation in this case would look like:
```yml ```yml
@ -180,7 +158,6 @@ would now look like:
- name: Publish package to PyPI - name: Publish package to PyPI
uses: pypa/gh-action-pypi-publish@release/v1 uses: pypa/gh-action-pypi-publish@release/v1
with: with:
password: ${{ secrets.PYPI_API_TOKEN }}
packages-dir: custom-dir/ packages-dir: custom-dir/
``` ```
@ -245,6 +222,18 @@ specify a custom username and password pair. This is how it's done.
password: ${{ secrets.DEVPI_PASSWORD }} password: ${{ secrets.DEVPI_PASSWORD }}
``` ```
The secret used in `${{ secrets.DEVPI_PASSWORD }}` needs to be created on the
environment page under the settings of your project on GitHub.
See [Creating & using secrets].
In the past, when publishing to PyPI, the most secure way of the access scoping
for automatic publishing was to use the [API tokens][PyPI API token] feature of
PyPI. One would make it project-scoped and save as an environment-bound secret
in their GitHub repository settings, naming it `${{ secrets.PYPI_API_TOKEN }}`,
for example. See [Creating & using secrets]. This is no longer encouraged when
publishing to PyPI or TestPyPI, in favor of [trusted publishing].
## License ## License
The Dockerfile and associated scripts and documentation in this project The Dockerfile and associated scripts and documentation in this project
@ -280,3 +269,5 @@ https://github.com/vshymanskyy/StandWithUkraine/blob/main/docs/README.md
[warehouse#12965]: https://github.com/pypi/warehouse/issues/12965 [warehouse#12965]: https://github.com/pypi/warehouse/issues/12965
[trusted publishing]: https://docs.pypi.org/trusted-publishers/ [trusted publishing]: https://docs.pypi.org/trusted-publishers/
[how to specify username and password]: #specifying-a-different-username