Skip to content

Commit

Permalink
chore: Check whether version in PR is already released (#12)
Browse files Browse the repository at this point in the history
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.

Same as apify/apify-sdk-python#127.
  • Loading branch information
fnesveda authored Oct 25, 2023
1 parent b6c751d commit 53a611a
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 14 deletions.
24 changes: 24 additions & 0 deletions .github/workflows/check_version_availability.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Check package version availability

on:
workflow_call:

jobs:
check_version_availability:
name: Check version availability
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.8"

- name: Install dependencies
run: make install-dev

- name: Check version availability
run: make check-version-availability
4 changes: 4 additions & 0 deletions .github/workflows/run_checks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ on:
pull_request:

jobs:
check_version_availability:
name: Check version availability
uses: ./.github/workflows/check_version_availability.yaml

lint_and_type_checks:
name: Run lint and type checks
uses: ./.github/workflows/lint_and_type_checks.yaml
Expand Down
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.PHONY: clean install-dev build publish twine-check lint unit-tests type-check check-code format check-changelog-entry
.PHONY: clean install-dev build publish twine-check lint unit-tests type-check check-code format check-version-availability check-changelog-entry

clean:
rm -rf build dist .mypy_cache .pytest_cache src/*.egg-info __pycache__
Expand Down Expand Up @@ -32,5 +32,8 @@ format:
python3 -m isort src tests
python3 -m autopep8 --in-place --recursive src tests

check-version-availability:
python3 scripts/check_version_availability.py

check-changelog-entry:
python3 scripts/check_version_in_changelog.py
13 changes: 13 additions & 0 deletions scripts/check_version_availability.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/usr/bin/env python3
from utils import get_current_package_version, get_published_package_versions

# Checks whether the current package version number was not already used in a published release.
if __name__ == '__main__':
current_version = get_current_package_version()

# Load the version numbers of the currently published versions from PyPI
published_versions = get_published_package_versions()

# We don't want to try to publish a version with the same version number as an already released stable version
if current_version in published_versions:
raise RuntimeError(f'The current version {current_version} was already released!')
15 changes: 2 additions & 13 deletions scripts/update_version_for_prerelease.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
#!/usr/bin/env python3

import json
import re
import sys
import urllib.request

from utils import PACKAGE_NAME, get_current_package_version, set_current_package_version
from utils import get_current_package_version, get_published_package_versions, set_current_package_version

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

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

# We don't want to publish a prerelease version with the same version number as an already released stable version
if current_version in published_versions:
Expand Down
16 changes: 16 additions & 0 deletions scripts/utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import json
import pathlib
import urllib.request

PACKAGE_NAME = 'apify_shared'
REPO_ROOT = pathlib.Path(__file__).parent.resolve() / '..'
Expand Down Expand Up @@ -36,3 +38,17 @@ def set_current_package_version(version: str) -> None:
pyproject_toml_file.seek(0)
pyproject_toml_file.write(''.join(updated_pyproject_toml_file_lines))
pyproject_toml_file.truncate()


# Load the version numbers of the currently published versions from PyPI
def get_published_package_versions() -> list:
package_info_url = f'https://pypi.org/pypi/{PACKAGE_NAME}/json'
try:
package_data = json.load(urllib.request.urlopen(package_info_url))
published_versions = list(package_data['releases'].keys())
# If the URL returns 404, it means the package has no releases yet (which is okay in our case)
except urllib.error.HTTPError as e:
if e.code != 404:
raise e
published_versions = []
return published_versions

0 comments on commit 53a611a

Please sign in to comment.