Skip to content

Commit 246d169

Browse files
authored
Merge pull request #8020 from pradyunsg/release/better-version-validation-that-allows-betas
Significantly improve release version validation
2 parents 4416e88 + de633cd commit 246d169

File tree

3 files changed

+60
-16
lines changed

3 files changed

+60
-16
lines changed

noxfile.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -155,9 +155,9 @@ def lint(session):
155155
# -----------------------------------------------------------------------------
156156
@nox.session(name="prepare-release")
157157
def prepare_release(session):
158-
version = release.get_version_from_arguments(session.posargs)
158+
version = release.get_version_from_arguments(session)
159159
if not version:
160-
session.error("Usage: nox -s prepare-release -- YY.N[.P]")
160+
session.error("Usage: nox -s prepare-release -- <version>")
161161

162162
session.log("# Ensure nothing is staged")
163163
if release.modified_files_in_git("--staged"):
@@ -190,7 +190,7 @@ def prepare_release(session):
190190

191191
@nox.session(name="build-release")
192192
def build_release(session):
193-
version = release.get_version_from_arguments(session.posargs)
193+
version = release.get_version_from_arguments(session)
194194
if not version:
195195
session.error("Usage: nox -s build-release -- YY.N[.P]")
196196

@@ -249,7 +249,7 @@ def build_dists(session):
249249

250250
@nox.session(name="upload-release")
251251
def upload_release(session):
252-
version = release.get_version_from_arguments(session.posargs)
252+
version = release.get_version_from_arguments(session)
253253
if not version:
254254
session.error("Usage: nox -s upload-release -- YY.N[.P]")
255255

tools/automation/release/__init__.py

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,25 @@
1414
from nox.sessions import Session
1515

1616

17-
def get_version_from_arguments(arguments: List[str]) -> Optional[str]:
17+
def get_version_from_arguments(session: Session) -> Optional[str]:
1818
"""Checks the arguments passed to `nox -s release`.
1919
2020
If there is only 1 argument that looks like a pip version, returns that.
2121
Otherwise, returns None.
2222
"""
23-
if len(arguments) != 1:
23+
if len(session.posargs) != 1:
2424
return None
25-
26-
version = arguments[0]
27-
28-
parts = version.split('.')
29-
if not 2 <= len(parts) <= 3:
30-
# Not of the form: YY.N or YY.N.P
31-
return None
32-
33-
if not all(part.isdigit() for part in parts):
34-
# Not all segments are integers.
25+
version = session.posargs[0]
26+
27+
# We delegate to a script here, so that it can depend on packaging.
28+
session.install("packaging")
29+
cmd = [
30+
os.path.join(session.bin, "python"),
31+
"tools/automation/release/check_version.py",
32+
version
33+
]
34+
not_ok = subprocess.run(cmd).returncode
35+
if not_ok:
3536
return None
3637

3738
# All is good.
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
"""Checks if the version is acceptable, as per this project's release process.
2+
"""
3+
4+
import sys
5+
from datetime import datetime
6+
from typing import Optional
7+
8+
from packaging.version import InvalidVersion, Version
9+
10+
11+
def is_this_a_good_version_number(string: str) -> Optional[str]:
12+
try:
13+
v = Version(string)
14+
except InvalidVersion as e:
15+
return str(e)
16+
17+
if v.local:
18+
return "Nope. PyPI refuses local release versions."
19+
20+
if v.dev:
21+
return "No development releases on PyPI. What are you even thinking?"
22+
23+
if v.is_prerelease and v.pre[0] != "b":
24+
return "Only beta releases are allowed. No alphas."
25+
26+
release = v.release
27+
expected_major = datetime.now().year % 100
28+
29+
if len(release) not in [2, 3]:
30+
return "Not of the form: {0}.N or {0}.N.P".format(expected_major)
31+
32+
return None
33+
34+
35+
def main() -> None:
36+
problem = is_this_a_good_version_number(sys.argv[1])
37+
if problem is not None:
38+
print("ERROR:", problem)
39+
sys.exit(1)
40+
41+
42+
if __name__ == "__main__":
43+
main()

0 commit comments

Comments
 (0)