Skip to content

Commit e59a573

Browse files
authored
chore: Check whether version in PR is already released (#127)
We have a recurring issue that you often forget to bump the package version number in a PR, and then when you merge it to `master`, the package publication fails because the version you're trying to publish already exists. This adds a check to CI which detects these issues early and fails the CI, so you can't merge those PRs without bumping the package version number. It gets skipped if the title of the PR is `docs: ...`, because such PRs don't trigger package publication when merged.
1 parent e287144 commit e59a573

File tree

6 files changed

+64
-14
lines changed

6 files changed

+64
-14
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
name: Check package version availability
2+
3+
on:
4+
workflow_call:
5+
6+
jobs:
7+
check_version_availability:
8+
name: Check version availability
9+
runs-on: ubuntu-latest
10+
if: (!startsWith(github.event.pull_request.title, 'docs:'))
11+
12+
steps:
13+
- name: Checkout repository
14+
uses: actions/checkout@v4
15+
16+
- name: Set up Python
17+
uses: actions/setup-python@v4
18+
with:
19+
python-version: "3.8"
20+
21+
- name: Install dependencies
22+
run: make install-dev
23+
24+
- name: Check version availability
25+
run: make check-version-availability

.github/workflows/run_checks.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ on:
44
pull_request:
55

66
jobs:
7+
check_version_availability:
8+
name: Check version availability
9+
uses: ./.github/workflows/check_version_availability.yaml
10+
711
lint_and_type_checks:
812
name: Run lint and type checks
913
uses: ./.github/workflows/lint_and_type_checks.yaml

Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.PHONY: clean install-dev build publish twine-check lint unit-tests integration-tests type-check check-code format check-changelog-entry build-api-reference
1+
.PHONY: clean install-dev build publish twine-check lint unit-tests integration-tests type-check check-code format check-version-availability check-changelog-entry build-api-reference
22

33
# This is default for local testing, but GitHub workflows override it to a higher value in CI
44
INTEGRATION_TESTS_CONCURRENCY = 1
@@ -38,6 +38,9 @@ format:
3838
python3 -m isort src tests
3939
python3 -m autopep8 --in-place --recursive src tests
4040

41+
check-version-availability:
42+
python3 scripts/check_version_availability.py
43+
4144
check-changelog-entry:
4245
python3 scripts/check_version_in_changelog.py
4346

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#!/usr/bin/env python3
2+
from utils import get_current_package_version, get_published_package_versions
3+
4+
# Checks whether the current package version number was not already used in a published release.
5+
if __name__ == '__main__':
6+
current_version = get_current_package_version()
7+
8+
# Load the version numbers of the currently published versions from PyPI
9+
published_versions = get_published_package_versions()
10+
11+
# We don't want to try to publish a version with the same version number as an already released stable version
12+
if current_version in published_versions:
13+
raise RuntimeError(f'The current version {current_version} was already released!')

scripts/update_version_for_prerelease.py

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
#!/usr/bin/env python3
22

3-
import json
43
import re
54
import sys
6-
import urllib.request
75

8-
from utils import PACKAGE_NAME, get_current_package_version, set_current_package_version
6+
from utils import get_current_package_version, get_published_package_versions, set_current_package_version
97

108
# Checks whether the current package version number was not already used in a published release,
119
# and if not, modifies the package version number in pyproject.toml
@@ -32,16 +30,7 @@
3230
raise RuntimeError(f'The current version {current_version} does not match the proper semver format for stable releases (X.Y.Z)')
3331

3432
# Load the version numbers of the currently published versions from PyPI
35-
# If the URL returns 404, it means the package has no releases yet (which is okay in our case)
36-
package_info_url = f'https://pypi.org/pypi/{PACKAGE_NAME}/json'
37-
try:
38-
conn = urllib.request.urlopen(package_info_url)
39-
package_data = json.load(urllib.request.urlopen(package_info_url))
40-
published_versions = list(package_data['releases'].keys())
41-
except urllib.error.HTTPError as e:
42-
if e.code != 404:
43-
raise e
44-
published_versions = []
33+
published_versions = get_published_package_versions()
4534

4635
# We don't want to publish a prerelease version with the same version number as an already released stable version
4736
if current_version in published_versions:

scripts/utils.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
import json
12
import pathlib
3+
import urllib.request
24

35
PACKAGE_NAME = 'apify'
46
REPO_ROOT = pathlib.Path(__file__).parent.resolve() / '..'
@@ -36,3 +38,17 @@ def set_current_package_version(version: str) -> None:
3638
pyproject_toml_file.seek(0)
3739
pyproject_toml_file.write(''.join(updated_pyproject_toml_file_lines))
3840
pyproject_toml_file.truncate()
41+
42+
43+
# Load the version numbers of the currently published versions from PyPI
44+
def get_published_package_versions() -> list:
45+
package_info_url = f'https://pypi.org/pypi/{PACKAGE_NAME}/json'
46+
try:
47+
package_data = json.load(urllib.request.urlopen(package_info_url))
48+
published_versions = list(package_data['releases'].keys())
49+
# If the URL returns 404, it means the package has no releases yet (which is okay in our case)
50+
except urllib.error.HTTPError as e:
51+
if e.code != 404:
52+
raise e
53+
published_versions = []
54+
return published_versions

0 commit comments

Comments
 (0)