Skip to content

Commit b852020

Browse files
webknjazhugovkdi
authored andcommitted
Add a guide about publishing dists via GH Actions (#647)
* Add a guide about publishing dists via GH Actions Co-Authored-By: Hugo van Kemenade <[email protected]> Co-Authored-By: Dustin Ingram <[email protected]>
1 parent fb64a4d commit b852020

File tree

3 files changed

+195
-0
lines changed

3 files changed

+195
-0
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
name: Publish Python 🐍 distributions 📦 to PyPI and TestPyPI
2+
3+
on: push
4+
5+
jobs:
6+
build-n-publish:
7+
name: Build and publish Python 🐍 distributions 📦 to PyPI and TestPyPI
8+
runs-on: ubuntu-18.04
9+
10+
steps:
11+
- uses: actions/checkout@master
12+
- name: Set up Python 3.7
13+
uses: actions/setup-python@v1
14+
with:
15+
version: 3.7
16+
- name: Install pep517
17+
run: >-
18+
python -m
19+
pip install
20+
pep517
21+
--user
22+
- name: Build a binary wheel and a source tarball
23+
run: >-
24+
python -m
25+
pep517.build
26+
--source
27+
--binary
28+
--out-dir dist/
29+
.
30+
# Actually publish to PyPI/TestPyPI
31+
- name: Publish distribution 📦 to Test PyPI
32+
uses: pypa/gh-action-pypi-publish@master
33+
with:
34+
password: ${{ secrets.test_pypi_password }}
35+
repository_url: https://test.pypi.org/legacy/
36+
- name: Publish distribution 📦 to PyPI
37+
if: startsWith(github.event.ref, 'refs/tags')
38+
uses: pypa/gh-action-pypi-publish@master
39+
with:
40+
password: ${{ secrets.pypi_password }}

source/guides/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,4 @@ introduction to packaging, see :doc:`/tutorials/index`.
2929
migrating-to-pypi-org
3030
using-testpypi
3131
making-a-pypi-friendly-readme
32+
publishing-package-distribution-releases-using-github-actions-ci-cd-workflows
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
=============================================================================
2+
Publishing package distribution releases using GitHub Actions CI/CD workflows
3+
=============================================================================
4+
5+
`GitHub Actions CI/CD`_ allows you to run a series of commands
6+
whenever an event occurs on the GitHub platform. One
7+
popular choice is having a workflow that's triggered by a
8+
``push`` event.
9+
This guide shows you how to publish a Python distribution
10+
whenever a tagged commit is pushed.
11+
It will use the `pypa/gh-action-pypi-publish GitHub Action`_ https://github.com/marketplace/actions/pypi-publish
12+
13+
.. attention::
14+
15+
This guide *assumes* that you already have a project that
16+
you know how to build distributions for and *it lives on GitHub*.
17+
18+
.. warning::
19+
20+
At the time of writing, `GitHub Actions CI/CD`_
21+
is in public beta. If you don't have it enabled,
22+
you should `join the waitlist`_ to gain access.
23+
24+
25+
Saving credentials on GitHub
26+
============================
27+
28+
In this guide, we'll demonstrate uploading to both
29+
PyPI and TestPyPI, meaning that we'll have two separate sets
30+
of credentials. And we'll need to save them in the GitHub repository
31+
settings.
32+
33+
Let's begin! 🚀
34+
35+
1. Go to https://pypi.org/manage/account/#api-tokens and
36+
create a new `API token`_. If you have the project on PyPI
37+
already, limit the token scope to just that project.
38+
You can call it something like
39+
``GitHub Actions CI/CD — project-org/project-repo``
40+
in order for it to be easily distinguishable in the token
41+
list.
42+
**Don't close the page just yet — you won't see that token
43+
again.**
44+
2. In a separate browser tab or window, go to the ``Settings``
45+
tab of your target repository and then click on `Secrets`_
46+
in the left sidebar.
47+
3. Create a new secret called ``pypi_password`` and copy-paste
48+
the token from the fist step.
49+
4. Now, go to https://test.pypi.org/manage/account/#api-tokens
50+
and repeat the steps. Save that TestPyPI token on GitHub
51+
as ``test_pypi_password``.
52+
53+
.. attention::
54+
55+
If you don't have a TestPyPI account, you'll need to
56+
create it. It's not the same as a regular PyPI account.
57+
58+
59+
Creating a workflow definition
60+
==============================
61+
62+
GitHub CI/CD workflows are declared in YAML files stored in the
63+
``.github/workflows/`` directory of your repository.
64+
65+
Let's create a ``.github/workflows/publish-to-test-pypi.yml``
66+
file.
67+
68+
Start it with a meaningful name and define the event that
69+
should make GitHub run this workflow:
70+
71+
.. literalinclude:: github-actions-ci-cd-sample/publish-to-test-pypi.yml
72+
:language: yaml
73+
:end-before: jobs:
74+
75+
76+
Defining a workflow job environment
77+
===================================
78+
79+
Now, let's add initial setup for our job. It's a process that
80+
will execute commands that we'll define later.
81+
In this guide, we'll use Ubuntu 18.04:
82+
83+
.. literalinclude:: github-actions-ci-cd-sample/publish-to-test-pypi.yml
84+
:language: yaml
85+
:start-after: on:
86+
:end-before: steps:
87+
88+
89+
Checking out the project and building distributions
90+
===================================================
91+
92+
Then, add the following under the ``build-n-publish`` section:
93+
94+
.. literalinclude:: github-actions-ci-cd-sample/publish-to-test-pypi.yml
95+
:language: yaml
96+
:start-after: runs-on:
97+
:end-before: Install pep517
98+
99+
This will download your repository into the CI runner and then
100+
install and activate Python 3.7.
101+
102+
And now we can build dists from source. In this example, we'll
103+
use ``pep517`` package, assuming that your project has a
104+
``pyproject.toml`` properly set up (see
105+
:pep:`517`/:pep:`518`).
106+
107+
.. tip::
108+
109+
You can use any other method for building distributions as long as
110+
it produces ready-to-upload artifacts saved into the
111+
``dist/`` folder.
112+
113+
So add this to the steps list:
114+
115+
.. literalinclude:: github-actions-ci-cd-sample/publish-to-test-pypi.yml
116+
:language: yaml
117+
:start-after: version: 3.7
118+
:end-before: Actually publish to PyPI/TestPyPI
119+
120+
121+
Publishing the distribution to PyPI and TestPyPI
122+
================================================
123+
124+
Finally, add the following steps at the end:
125+
126+
.. literalinclude:: github-actions-ci-cd-sample/publish-to-test-pypi.yml
127+
:language: yaml
128+
:start-after: Actually publish to PyPI/TestPyPI
129+
130+
These two steps use the `pypa/gh-action-pypi-publish`_ GitHub
131+
Action: the first one uploads contents of the ``dist/`` folder
132+
into TestPyPI unconditionally and the second does that to
133+
PyPI, but only if the current commit is tagged.
134+
135+
136+
That's all, folks!
137+
==================
138+
139+
Now, whenever you push a tagged commit to your Git repository remote
140+
on GitHub, this workflow will publish it to PyPI.
141+
And it'll publish any push to TestPyPI which is useful for
142+
providing test builds to your alpha users as well as making
143+
sure that your release pipeline remains healthy!
144+
145+
146+
.. _API token: https://pypi.org/help/#apitoken
147+
.. _GitHub Actions CI/CD: https://github.com/features/actions
148+
.. _join the waitlist: https://github.com/features/actions/signup
149+
.. _pypa/gh-action-pypi-publish:
150+
https://github.com/pypa/gh-action-pypi-publish
151+
.. _`pypa/gh-action-pypi-publish GitHub Action`:
152+
https://github.com/marketplace/actions/pypi-publish
153+
.. _Secrets:
154+
https://help.github.com/en/articles/virtual-environments-for-github-actions#creating-and-using-secrets-encrypted-variables

0 commit comments

Comments
 (0)