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 PyPI trusted publisher as an option #93

Merged
merged 15 commits into from
Mar 4, 2024
5 changes: 0 additions & 5 deletions .github/workflows/_pypi.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
on:
workflow_call:
secrets:
PYPI_TOKEN:
required: true

jobs:
upload:
Expand All @@ -18,5 +15,3 @@ jobs:

- name: Publish to PyPI using trusted publishing
uses: pypa/gh-action-pypi-publish@release/v1
with:
password: ${{ secrets.PYPI_TOKEN }}
5 changes: 5 additions & 0 deletions catalog-info.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@ spec:
enum:
- pyright
- mypy
pypi:
title: PyPI?
description: Would you like the wheel and source distribution to be automatically uploaded to PyPI when a release is made?
type: boolean
default: false

# This template is meant to be used on top of an existing template.
# By adding the following and fetching from an absolute URL you can
Expand Down
11 changes: 11 additions & 0 deletions copier.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ type_checker:
- pyright
- mypy

pypi:
type: bool
help: Would you like the wheel and source distribution to be automatically uploaded to PyPI when a release is made?

# Internal variables
repo_url:
type: str
Expand All @@ -106,3 +110,10 @@ _subdirectory: "template"

_tasks:
- "git init --initial-branch=main"

_migrations:
- version: 2.0.0
before:
- echo This update will require you to login to pypi.org and make changes before you can make a new release to PyPI. If you do not have time to do this now, press CTRL+C to abort this update.
after:
- echo Visit https://diamondlightsource.github.io/python-copier-template/main/how-to/pypi.html to find out how to set up PyPI trusted publishing
26 changes: 18 additions & 8 deletions docs/how-to/pypi.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
# Creating a PyPI Token
# Setting up PyPI publishing

To publish your package on PyPI requires a PyPI account and for GitHub Actions to have a PyPI token authorizing access to that account.
To publish your package on PyPI requires a PyPI account and for PyPI to be setup for [Trusted Publisher](https://docs.pypi.org/trusted-publishers/).

The simplest approach is to set up a PyPI token that is scoped to your PyPI account and add it to the secrets for your GitHub Organization (or user). This means that all new projects created in the Organization will automatically gain permission to publish to PyPI.
## Gather the information

Alternatively you can create a project scoped token for each project. This is more work but more secure as a bad actor that obtains the key can only affect a single project.
You will need the following information:

If you do not already have a PyPI account use this link: [create_account].
- Owner: The GitHub org that the repo is contained in, e.g. `DiamondLightSource`
- Repository name: The GitHub repository name, e.g. `python-copier-template-example`
- PyPI Project Name: The distribution name on PyPI, e.g. `dls-python-copier-template-example`
- Workflow name: The workflow that does publishing, `_pypi.yml` for `python-copier-template` projects
- Environment name: The GitHub environment that publishing is done with, `release` for `python-copier-template` projects

To learn how to create a token and store it in Github see: [adding_a_token]. You can ignore the other sections of the page regarding Github Actions because these are already provided by skeleton. Note that skeleton uses `PYPI_TOKEN` as the secret name instead of `PYPI_API_TOKEN` described in the link.
## If publishing to the DiamondLightSource PyPI organisation

[adding_a_token]: https://packaging.python.org/en/latest/guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows/#saving-credentials-on-github
[create_account]: https://pypi.org/account/register/
If you are publishing to the DiamondLightSource PyPI organisation then use the above information and follow the [Developer Portal Guide on PyPI publishing](https://dev-portal.diamond.ac.uk/guide/python/how-tos/pypi/).

## If publishing the PyPI project to another organisation

If you are publishing to a different PyPI organisation then use the above information in one of the following guides:

- [Creating a PyPI project with a trusted publisher](https://docs.pypi.org/trusted-publishers/creating-a-project-through-oidc/)
- [Adding a trusted publisher to an existing PyPI project](https://docs.pypi.org/trusted-publishers/adding-a-publisher/)
1 change: 1 addition & 0 deletions example-answers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ github_org: DiamondLightSource
package_name: python_copier_template_example
repo_name: python-copier-template-example
type_checker: pyright
pypi: true
14 changes: 7 additions & 7 deletions template/README.md.jinja
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[![CI]({{repo_url}}/actions/workflows/ci.yml/badge.svg)]({{repo_url}}/actions/workflows/ci.yml)
[![Coverage](https://codecov.io/gh/{{github_org}}/{{repo_name}}/branch/main/graph/badge.svg)](https://codecov.io/gh/{{github_org}}/{{repo_name}})
[![PyPI](https://img.shields.io/pypi/v/{{distribution_name}}.svg)](https://pypi.org/project/{{distribution_name}})
{% if pypi %}[![PyPI](https://img.shields.io/pypi/v/{{distribution_name}}.svg)](https://pypi.org/project/{{distribution_name}}){% endif %}
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)

# {{ package_name }}
Expand All @@ -10,12 +10,12 @@
This is where you should write a short paragraph that describes what your module does,
how it does it, and why people should use it.

Source | <{{repo_url}}>
:---: | :---:
PyPI | `pip install {{distribution_name}}`
{% if docker %}Docker | `docker run ghcr.io/{{github_org | lower}}/{{repo_name}}:latest`
{% endif %}{% if sphinx %}Documentation | <{{docs_url}}>{% endif %}
Releases | <{{repo_url}}/releases>
{% if True %}Source | <{{repo_url}}>
{% endif %}{% if True %}:---: | :---:
{% endif %}{% if pypi %}PyPI | `pip install {{distribution_name}}`
{% endif %}{% if docker %}Docker | `docker run ghcr.io/{{github_org | lower}}/{{repo_name}}:latest`
{% endif %}{% if sphinx %}Documentation | <{{docs_url}}>
{% endif %}Releases | <{{repo_url}}/releases>

This is where you should put some images or code snippets that illustrate
some relevant examples. If it is a library then you might put some
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,14 @@ jobs:
needs: check
if: needs.check.outputs.branch-pr == ''
uses: ./.github/workflows/_dist.yml
{% raw %}
{% if pypi %}
pypi:
if: github.ref_type == 'tag'
needs: dist
uses: ./.github/workflows/_pypi.yml
permissions:
id-token: write
secrets:
PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
{% endraw %}
{% endif %}
release:
if: github.ref_type == 'tag'
needs: [dist{% if sphinx %}, docs{% endif %}]
Expand Down
Loading