Skip to content

Commit eee6fe0

Browse files
URL Inference (#3)
1 parent b43462b commit eee6fe0

File tree

3 files changed

+149
-44
lines changed

3 files changed

+149
-44
lines changed

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM python:3.7.3
1+
FROM python:3.7
22

33
LABEL "com.github.actions.name"="PyPI"
44
LABEL "com.github.actions.description"="Upload the release to PyPI when published on GitHub."

README.md

Lines changed: 69 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,81 @@
1-
# gh-action-pypi-upload
2-
Use this GitHub action to upload a Python package to PyPi
1+
# GitHub Action - PyPI Upload
32

4-
## Prereqs
3+
Use this GitHub Action to upload a Python package to PyPI.
54

6-
* You can `pip install` the library locally and import it
5+
## Install
76

8-
## Usage
7+
In your repository, add the following lines to `.github/workflows/release.yml`:
98

10-
Add the following lines to `.github/main.workflow`
9+
```yaml
10+
on:
11+
release:
12+
types: [published]
1113

14+
name: Release
15+
jobs:
16+
pypi:
17+
name: Release to PyPI
18+
runs-on: ubuntu-latest
19+
steps:
20+
- uses: actions/checkout@master
21+
- name: Upload to PyPI
22+
uses: FeatureLabs/gh-action-pypi-upload@master
23+
env:
24+
PYPI_USERNAME: ${{ secrets.PYPI_USERNAME }}
25+
PYPI_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
26+
TEST_PYPI_USERNAME: ${{ secrets.TEST_PYPI_USERNAME }}
27+
TEST_PYPI_PASSWORD: ${{ secrets.TEST_PYPI_PASSWORD }}
1228
```
13-
workflow "Release" {
14-
on = "release"
15-
resolves = ["PyPI"]
16-
}
1729
18-
action "PyPI" {
19-
uses = "FeatureLabs/gh-action-pypi-upload@master"
20-
secrets = ["PYPI_USERNAME", "PYPI_PASSWORD"]
21-
env = {
22-
TWINE_REPOSITORY_URL = "https://test.pypi.org/legacy/"
23-
}
24-
}
30+
Then, add the following secrets to the repository settings:
31+
- `PYPI_USERNAME`
32+
- `PYPI_PASSWORD`
33+
- `TEST_PYPI_USERNAME`
34+
- `TEST_PYPI_PASSWORD`
35+
36+
## Usage
37+
38+
The published release tag from GitHub will determine which repository the package is uploaded to. The tag schemes are based on the specifications in [PEP 440](https://www.python.org/dev/peps/pep-0440).
39+
40+
### Upload to Test PyPI
41+
42+
To upload a package to [Test PyPI](https://test.pypi.org/), the tag must follow the version schemes for [developmental releases](https://www.python.org/dev/peps/pep-0440/#developmental-releases).
43+
44+
#### Developmental releases
45+
46+
```
47+
X.Y.devN # Developmental release
48+
X.YaN.devM # Developmental release of an alpha release
49+
X.YbN.devM # Developmental release of a beta release
50+
X.YrcN.devM # Developmental release of a release candidate
51+
X.Y.postN.devM # Developmental release of a post-release
52+
```
53+
54+
### Upload to PyPI
55+
56+
To upload a package to [PyPI](https://pypi.org/), the tag can follow version schemes for [pre-releases](https://www.python.org/dev/peps/pep-0440/#pre-releases), [final releases](https://www.python.org/dev/peps/pep-0440/#final-releases), or [post-releases](https://www.python.org/dev/peps/pep-0440/#post-releases).
57+
58+
#### Pre-releases
59+
60+
```
61+
X.YaN # Alpha release
62+
X.YbN # Beta release
63+
X.YrcN # Release Candidate
2564
```
2665
27-
* Update `PYPI_USERNAME`, `PYPI_PASSWORD` secrets in repo settings
66+
#### Final releases
2867
29-
*Note: Once you release a version of your package to PyPi you cannot rerelease that same version number, even if you delete it*
68+
```
69+
X.Y # Final release
70+
```
71+
72+
#### Post-releases
3073
31-
* Make a test release and confirm the repo shows up on [TestPyPI](https://test.pypi.org/)
74+
```
75+
X.Y.postN # Post-release
76+
X.YaN.postM # Post-release of an alpha release
77+
X.YbN.postM # Post-release of a beta release
78+
X.YrcN.postM # Post-release of a release candidate
79+
```
3280
33-
* If it works, change `TWINE_REPOSITORY_URL = "https://upload.pypi.org/legacy/"` to point to production PyPi server
81+
*Note: Once you release a version of your package to PyPI, you cannot rerelease that same version number even if you delete it.*

upload.sh

Lines changed: 79 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,101 @@
11
#!/bin/sh
22

3-
# Get tag from environment
3+
# Get release tag from environment and checkout branch.
44
tag=$(basename $GITHUB_REF)
5+
git checkout tags/$tag
56

6-
# Get action that triggered release event
7+
# Get package version.
8+
version=$(python setup.py --version)
9+
10+
# Check if release tag matches the package version.
11+
pip install --quiet "packaging>=17.0"
12+
13+
match=$(python -c "
14+
from packaging.version import parse
15+
16+
match = parse('$tag') == parse('$version')
17+
print(match)
18+
")
19+
20+
if [ $match != "True" ]; then
21+
echo "Release $tag does not match package $version"
22+
exit 1
23+
fi
24+
25+
# Get action that triggered event.
726
action=$(python -c "
827
import json
28+
929
with open('$GITHUB_EVENT_PATH', 'r') as file:
1030
event = json.load(file)
1131
action = event.get('action')
32+
1233
print(action)
1334
")
1435

15-
echo "Release $tag was $action on GitHub ..."
36+
# Infer which repository to use.
37+
repository=$(python -c "
38+
from packaging.version import parse, Version
1639
17-
upload_to_pypi () {
18-
# Checkout specified tag
19-
git checkout tags/$tag
40+
version = parse('$tag')
41+
if isinstance(version, Version):
42+
repository = 'Test PyPI' if version.is_devrelease else 'PyPI'
43+
print(repository)
44+
")
2045

21-
# Remove build artifacts
46+
build_package() {
47+
# Remove build artifacts.
2248
rm -rf .eggs/ rm -rf dist/ rm -rf build/
2349

24-
# Create distributions
25-
python setup.py -q sdist bdist_wheel
50+
# Create distributions.
51+
python setup.py --quiet sdist bdist_wheel
52+
}
53+
54+
upload_package() {
55+
# Build the package to upload.
56+
build_package
57+
58+
# Create and activate the virtualenv to download twine.
59+
python -m venv venv; . venv/bin/activate
2660

27-
# Create virtualenv to download twine
28-
python -m venv venv
29-
. venv/bin/activate
30-
31-
# Upgrade pip
32-
python -m pip install --upgrade pip -q
61+
# Upgrade pip.
62+
python -m pip install --quiet --upgrade pip
3363

34-
# Install twine, module used to upload to pypi
35-
python -m pip install twine -q
64+
# Install twine which is used to upload the package.
65+
python -m pip --quiet install twine
3666

37-
# Upload to pypi or testpypi, overwrite if files already exist.
67+
echo
68+
echo "---------- Uploading to $repository --------------------"
69+
echo
70+
71+
# Upload the package to PyPI or Test PyPI. Overwrite if files already exist.
3872
python -m twine upload dist/* --skip-existing --verbose \
39-
--username $PYPI_USERNAME --password $PYPI_PASSWORD \
40-
--repository-url $TWINE_REPOSITORY_URL
73+
--username $1 --password $2 --repository-url $3
4174
}
4275

43-
# If release was published on GitHub then upload to PyPI
44-
if [ $action = "published" ]; then upload_to_pypi; fi
76+
release_package() {
77+
# If the inferred repository is PyPI, then release to PyPI.
78+
if [ "$repository" = "PyPI" ]; then
79+
TWINE_REPOSITORY_URL="https://upload.pypi.org/legacy/"
80+
upload_package $PYPI_USERNAME $PYPI_PASSWORD $TWINE_REPOSITORY_URL
81+
82+
# Else if the inferred repository is Test PyPI, then release to Test PyPI.
83+
elif [ "$repository" = "Test PyPI" ]; then
84+
TWINE_REPOSITORY_URL="https://test.pypi.org/legacy/"
85+
upload_package $TEST_PYPI_USERNAME $TEST_PYPI_PASSWORD $TWINE_REPOSITORY_URL
86+
87+
# Else, raise an error and exit.
88+
else
89+
echo "Unable to make inference on release $tag"
90+
exit 1
91+
fi
92+
}
93+
94+
echo
95+
echo "=================================================="
96+
echo "Release $tag was $action on GitHub"
97+
echo "=================================================="
98+
echo
99+
100+
# If release was published on GitHub then release package.
101+
if [ $action = "published" ]; then release_package; fi

0 commit comments

Comments
 (0)