Skip to content

Commit b8b225b

Browse files
jcfrhenryiii
andauthored
Revisit versioning and streamline maintenance adding "bump" and "tag_release" nox sessions (#13)
* feat: simplify versioning by hard-coding value in pyproject.toml This major version associated with the package is now consistent with the IDC table version hard-coded in `scripts/sql/idc_index.sql`. Co-authored-by: Henry Schreiner <[email protected]> * chore: Add "bump" nox session to streamline IDC index version update Co-authored-by: Henry Schreiner <[email protected]> * chore: Add nox session and instructions for tagging a release Co-authored-by: Henry Schreiner <[email protected]> --------- Co-authored-by: Henry Schreiner <[email protected]>
1 parent bdffbdb commit b8b225b

File tree

6 files changed

+215
-8
lines changed

6 files changed

+215
-8
lines changed

.github/CONTRIBUTING.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,3 +99,24 @@ pre-commit run -a
9999
```
100100

101101
to check all files.
102+
103+
# Updating the IDC index version
104+
105+
You can update the version using:
106+
107+
```bash
108+
export GCP_PROJECT=idc-external-025
109+
export GOOGLE_APPLICATION_CREDENTIALS=/path/to/keyfile.json
110+
nox -s bump -- <version>
111+
```
112+
113+
And follow the instructions it gives you. Leave off the version to bump to the
114+
latest version. Add `-–commit` to run the commit procedure.
115+
116+
# Tagging a release
117+
118+
You can print the instructions for tagging a release using:
119+
120+
```bash
121+
nox -s tag_release
122+
```

noxfile.py

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
from __future__ import annotations
22

33
import argparse
4+
import re
45
import shutil
56
from pathlib import Path
67

78
import nox
89

910
DIR = Path(__file__).parent.resolve()
1011

11-
nox.options.sessions = ["lint", "pylint", "tests"]
12+
nox.options.sessions = ["lint", "pylint", "tests"] # Session run by default
1213

1314

1415
@nox.session
@@ -115,3 +116,90 @@ def build(session: nox.Session) -> None:
115116

116117
session.install("build")
117118
session.run("python", "-m", "build")
119+
120+
121+
def _bump(session: nox.Session, name: str, script: str, files) -> None:
122+
parser = argparse.ArgumentParser()
123+
parser.add_argument(
124+
"--commit", action="store_true", help="Make a branch and commit."
125+
)
126+
parser.add_argument(
127+
"version", nargs="?", help="The version to process - leave off for latest."
128+
)
129+
args = parser.parse_args(session.posargs)
130+
131+
session.install("db-dtypes")
132+
session.install("google-cloud-bigquery")
133+
session.install("pandas")
134+
session.install("pyarrow")
135+
136+
if args.version is None:
137+
gcp_project = "idc-external-025"
138+
idc_index_version = session.run(
139+
"python",
140+
"scripts/python/idc_index_data_manager.py",
141+
"--project",
142+
gcp_project,
143+
"--retrieve-latest-idc-release-version",
144+
external=True,
145+
silent=True,
146+
).strip()
147+
148+
else:
149+
idc_index_version = args.version
150+
151+
extra = ["--quiet"] if args.commit else []
152+
session.run("python", script, idc_index_version, *extra)
153+
154+
if args.commit:
155+
session.run(
156+
"git",
157+
"switch",
158+
"-c",
159+
f"update-to-{name.replace(' ', '-').lower()}-{idc_index_version}",
160+
external=True,
161+
)
162+
session.run("git", "add", "-u", *files, external=True)
163+
session.run(
164+
"git",
165+
"commit",
166+
"-m",
167+
f"Update to {name} {idc_index_version}",
168+
external=True,
169+
)
170+
session.log(
171+
f'Complete! Now run: gh pr create --fill --body "Created by running `nox -s {session.name} -- --commit`"'
172+
)
173+
174+
175+
@nox.session
176+
def bump(session: nox.Session) -> None:
177+
"""
178+
Set to a new IDC index version, use -- <version>, otherwise will use the latest version.
179+
"""
180+
files = (
181+
"pyproject.toml",
182+
"scripts/sql/idc_index.sql",
183+
"tests/test_package.py",
184+
)
185+
_bump(
186+
session,
187+
"IDC index",
188+
"scripts/python/update_idc_index_version.py",
189+
files,
190+
)
191+
192+
193+
@nox.session(venv_backend="none")
194+
def tag_release(session: nox.Session) -> None:
195+
"""
196+
Print instructions for tagging a release and pushing it to GitHub.
197+
"""
198+
199+
session.log("Run the following commands to make a release:")
200+
txt = Path("pyproject.toml").read_text()
201+
current_version = next(iter(re.finditer(r'^version = "([\d\.]+)$"', txt))).group(1)
202+
print(
203+
f"git tag --sign -m 'idc-index-data {current_version}' {current_version} main"
204+
)
205+
print(f"git push origin {current_version}")

pyproject.toml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ build-backend = "scikit_build_core.build"
1313

1414
[project]
1515
name = "idc-index-data"
16+
version = "17.0.0"
1617
authors = [
1718
{ name = "Andrey Fedorov", email = "[email protected]" },
1819
{ name = "Vamsi Thiriveedhi", email = "[email protected]" },
@@ -39,7 +40,6 @@ classifiers = [
3940
"Topic :: Scientific/Engineering",
4041
"Typing :: Typed",
4142
]
42-
dynamic = ["version"]
4343
dependencies = []
4444

4545
[project.optional-dependencies]
@@ -69,15 +69,15 @@ Changelog = "https://github.com/ImagingDataCommons/idc-index-data/releases"
6969
[tool.scikit-build]
7070
minimum-version = "0.8.2"
7171
build-dir = "build/{wheel_tag}"
72-
metadata.version.provider = "scikit_build_core.metadata.setuptools_scm"
73-
sdist.include = ["src/idc_index_data/_version.py"]
7472
wheel.platlib = false
7573
wheel.py-api = "py3"
7674

7775

78-
[tool.setuptools_scm]
79-
write_to = "src/idc_index_data/_version.py"
80-
version_scheme = "no-guess-dev"
76+
[[tool.scikit-build.generate]]
77+
path = "idc_index_data/_version.py"
78+
template = '''
79+
version = "${version}"
80+
'''
8181

8282

8383
[tool.pytest.ini_options]
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Command line executable allowing to update source files given a IDC index version.
4+
"""
5+
6+
from __future__ import annotations
7+
8+
import argparse
9+
import contextlib
10+
import os
11+
import re
12+
import textwrap
13+
from pathlib import Path
14+
15+
ROOT_DIR = Path(__file__).parent / "../.."
16+
17+
18+
@contextlib.contextmanager
19+
def _log(txt, verbose=True):
20+
if verbose:
21+
print(txt) # noqa: T201
22+
yield
23+
if verbose:
24+
print(f"{txt} - done") # noqa: T201
25+
26+
27+
def _update_file(filepath, regex, replacement):
28+
msg = "Updating %s" % os.path.relpath(str(filepath), ROOT_DIR)
29+
with _log(msg):
30+
pattern = re.compile(regex)
31+
with filepath.open() as doc_file:
32+
lines = doc_file.readlines()
33+
updated_content = []
34+
for line in lines:
35+
updated_content.append(re.sub(pattern, replacement, line))
36+
with filepath.open("w") as doc_file:
37+
doc_file.writelines(updated_content)
38+
39+
40+
def update_pyproject_toml(idc_index_version):
41+
pattern = re.compile(r'^version = "[\w\.]+"$')
42+
replacement = f'version = "{idc_index_version}.0.0"'
43+
_update_file(ROOT_DIR / "pyproject.toml", pattern, replacement)
44+
45+
46+
def update_sql_scripts(idc_index_version):
47+
pattern = re.compile(r"idc_v\d+")
48+
replacement = f"idc_v{idc_index_version}"
49+
_update_file(ROOT_DIR / "scripts/sql/idc_index.sql", pattern, replacement)
50+
51+
52+
def update_tests(idc_index_version):
53+
pattern = re.compile(r"EXPECTED_IDC_INDEX_VERSION = \d+")
54+
replacement = f"EXPECTED_IDC_INDEX_VERSION = {idc_index_version}"
55+
_update_file(ROOT_DIR / "tests/test_package.py", pattern, replacement)
56+
57+
58+
def main():
59+
parser = argparse.ArgumentParser(description=__doc__)
60+
parser.add_argument(
61+
"idc_index_version",
62+
metavar="IDC_INDEX_VERSION",
63+
type=int,
64+
help="IDC index version of the form NN",
65+
)
66+
parser.add_argument(
67+
"--quiet",
68+
action="store_true",
69+
help="Hide the output",
70+
)
71+
72+
args = parser.parse_args()
73+
74+
update_pyproject_toml(args.idc_index_version)
75+
update_sql_scripts(args.idc_index_version)
76+
update_tests(args.idc_index_version)
77+
78+
if not args.quiet:
79+
msg = """\
80+
Complete! Now run:
81+
82+
git switch -c update-to-idc-index-{release}
83+
git add -u pyproject.toml scripts/sql/idc_index.sql tests/test_package.py
84+
git commit -m "Update to IDC index {release}"
85+
gh pr create --fill --body "Created by update_idc_index_version.py"
86+
"""
87+
print(textwrap.dedent(msg.format(release=args.idc_index_version))) # noqa: T201
88+
89+
90+
if __name__ == "__main__":
91+
main()

src/idc_index_data/_version.pyi

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
from __future__ import annotations
22

33
version: str
4-
version_tuple: tuple[int, int, int] | tuple[int, int, int, str, str]

tests/test_package.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,21 @@
22

33
import importlib.metadata
44

5+
from packaging.version import Version
6+
57
import idc_index_data as m
68

9+
EXPECTED_IDC_INDEX_VERSION = 17
10+
711

812
def test_version():
913
assert importlib.metadata.version("idc_index_data") == m.__version__
1014

1115

16+
def test_idc_index_version():
17+
assert Version(m.__version__).major == EXPECTED_IDC_INDEX_VERSION
18+
19+
1220
def test_filepath():
1321
if m.IDC_INDEX_CSV_ARCHIVE_FILEPATH is not None:
1422
assert m.IDC_INDEX_CSV_ARCHIVE_FILEPATH.is_file()

0 commit comments

Comments
 (0)