mex-release 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Robert Koch-Institut
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,135 @@
1
+ Metadata-Version: 2.1
2
+ Name: mex-release
3
+ Version: 0.2.0
4
+ Summary: Create new release with `pdm release VERSION`
5
+ Author-Email: MEx Team <mex@rki.de>
6
+ License: MIT License
7
+
8
+ Copyright (c) 2024 Robert Koch-Institut
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Project-URL: Repository, https://github.com/robert-koch-institut/mex-release
29
+ Requires-Python: <3.13,>=3.11
30
+ Requires-Dist: pdm<3.0,>=2.13.2
31
+ Provides-Extra: dev
32
+ Requires-Dist: ipdb<1,>=0.13.13; extra == "dev"
33
+ Requires-Dist: mypy<2,>=1.11.0; extra == "dev"
34
+ Requires-Dist: ruff<1,>=0.5.4; extra == "dev"
35
+ Description-Content-Type: text/markdown
36
+
37
+ # MEx release
38
+
39
+ Create new release with `pdm release VERSION`
40
+
41
+ [![cookiecutter](https://github.com/robert-koch-institut/mex-release/actions/workflows/cookiecutter.yml/badge.svg)](https://github.com/robert-koch-institut/mex-template)
42
+ [![cve-scan](https://github.com/robert-koch-institut/mex-release/actions/workflows/cve-scan.yml/badge.svg)](https://github.com/robert-koch-institut/mex-release/actions/workflows/cve-scan.yml)
43
+ [![linting](https://github.com/robert-koch-institut/mex-release/actions/workflows/linting.yml/badge.svg)](https://github.com/robert-koch-institut/mex-release/actions/workflows/linting.yml)
44
+ [![open-code](https://github.com/robert-koch-institut/mex-release/actions/workflows/open-code.yml/badge.svg)](https://gitlab.opencode.de/robert-koch-institut/mex/mex-release)
45
+
46
+ ## project
47
+
48
+ The Metadata Exchange (MEx) project is committed to improve the retrieval of RKI
49
+ research data and projects. How? By focusing on metadata: instead of providing the
50
+ actual research data directly, the MEx metadata catalog captures descriptive information
51
+ about research data and activities. On this basis, we want to make the data FAIR[^1] so
52
+ that it can be shared with others.
53
+
54
+ Via MEx, metadata will be made findable, accessible and shareable, as well as available
55
+ for further research. The goal is to get an overview of what research data is available,
56
+ understand its context, and know what needs to be considered for subsequent use.
57
+
58
+ RKI cooperated with D4L data4life gGmbH for a pilot phase where the vision of a
59
+ FAIR metadata catalog was explored and concepts and prototypes were developed.
60
+ The partnership has ended with the successful conclusion of the pilot phase.
61
+
62
+ After an internal launch, the metadata will also be made publicly available and thus be
63
+ available to external researchers as well as the interested (professional) public to
64
+ find research data from the RKI.
65
+
66
+ For further details, please consult our
67
+ [project page](https://www.rki.de/DE/Content/Forsch/MEx/MEx_node.html).
68
+
69
+ [^1]: FAIR is referencing the so-called
70
+ [FAIR data principles](https://www.go-fair.org/fair-principles/) – guidelines to make
71
+ data Findable, Accessible, Interoperable and Reusable.
72
+
73
+ **Contact** \
74
+ For more information, please feel free to email us at [mex@rki.de](mailto:mex@rki.de).
75
+
76
+ ### Publisher of this document
77
+ **Robert Koch-Institut** \
78
+ Nordufer 20 \
79
+ 13353 Berlin \
80
+ Germany
81
+
82
+ ## package
83
+
84
+ Create a new release, including changelog rollover, project version bump, commit, tag
85
+ and push.
86
+
87
+ ## license
88
+
89
+ This package is licensed under the [MIT license](/LICENSE). All other software
90
+ components of the MEx project are open-sourced under the same license as well.
91
+
92
+ ## development
93
+
94
+ ### installation
95
+
96
+ - on unix, consider using pyenv https://github.com/pyenv/pyenv
97
+ - get pyenv `curl https://pyenv.run | bash`
98
+ - install 3.11 `pyenv install 3.11`
99
+ - switch version `pyenv global 3.11`
100
+ - run `make install`
101
+ - on windows, consider using pyenv-win https://pyenv-win.github.io/pyenv-win/
102
+ - follow https://pyenv-win.github.io/pyenv-win/#quick-start
103
+ - install 3.11 `pyenv install 3.11`
104
+ - switch version `pyenv global 3.11`
105
+ - run `.\mex.bat install`
106
+
107
+ ### linting and testing
108
+
109
+ - run all linters with `pdm lint`
110
+ - run only unit tests with `pdm unit`
111
+ - run unit and integration tests with `pdm test`
112
+
113
+ ### updating dependencies
114
+
115
+ - update boilerplate files with `cruft update`
116
+ - update global requirements in `requirements.txt` manually
117
+ - update git hooks with `pre-commit autoupdate`
118
+ - update package dependencies using `pdm update-all`
119
+ - update github actions in `.github/workflows/*.yml` manually
120
+
121
+ ### creating release
122
+
123
+ - run `pdm release RULE` to release a new version where RULE determines which part of
124
+ the version to update and is one of `major`, `minor`, `patch`.
125
+
126
+ ### container workflow
127
+
128
+ - build image with `make image`
129
+ - run directly using docker `make run`
130
+ - start with docker compose `make start`
131
+
132
+ ## commands
133
+
134
+ - run `pdm release VERSION` to release a new version where VERSION matches the regular
135
+ expression: `\d{1,4}\.\d{1,4}\.\d{1,4}`.
@@ -0,0 +1,99 @@
1
+ # MEx release
2
+
3
+ Create new release with `pdm release VERSION`
4
+
5
+ [![cookiecutter](https://github.com/robert-koch-institut/mex-release/actions/workflows/cookiecutter.yml/badge.svg)](https://github.com/robert-koch-institut/mex-template)
6
+ [![cve-scan](https://github.com/robert-koch-institut/mex-release/actions/workflows/cve-scan.yml/badge.svg)](https://github.com/robert-koch-institut/mex-release/actions/workflows/cve-scan.yml)
7
+ [![linting](https://github.com/robert-koch-institut/mex-release/actions/workflows/linting.yml/badge.svg)](https://github.com/robert-koch-institut/mex-release/actions/workflows/linting.yml)
8
+ [![open-code](https://github.com/robert-koch-institut/mex-release/actions/workflows/open-code.yml/badge.svg)](https://gitlab.opencode.de/robert-koch-institut/mex/mex-release)
9
+
10
+ ## project
11
+
12
+ The Metadata Exchange (MEx) project is committed to improve the retrieval of RKI
13
+ research data and projects. How? By focusing on metadata: instead of providing the
14
+ actual research data directly, the MEx metadata catalog captures descriptive information
15
+ about research data and activities. On this basis, we want to make the data FAIR[^1] so
16
+ that it can be shared with others.
17
+
18
+ Via MEx, metadata will be made findable, accessible and shareable, as well as available
19
+ for further research. The goal is to get an overview of what research data is available,
20
+ understand its context, and know what needs to be considered for subsequent use.
21
+
22
+ RKI cooperated with D4L data4life gGmbH for a pilot phase where the vision of a
23
+ FAIR metadata catalog was explored and concepts and prototypes were developed.
24
+ The partnership has ended with the successful conclusion of the pilot phase.
25
+
26
+ After an internal launch, the metadata will also be made publicly available and thus be
27
+ available to external researchers as well as the interested (professional) public to
28
+ find research data from the RKI.
29
+
30
+ For further details, please consult our
31
+ [project page](https://www.rki.de/DE/Content/Forsch/MEx/MEx_node.html).
32
+
33
+ [^1]: FAIR is referencing the so-called
34
+ [FAIR data principles](https://www.go-fair.org/fair-principles/) – guidelines to make
35
+ data Findable, Accessible, Interoperable and Reusable.
36
+
37
+ **Contact** \
38
+ For more information, please feel free to email us at [mex@rki.de](mailto:mex@rki.de).
39
+
40
+ ### Publisher of this document
41
+ **Robert Koch-Institut** \
42
+ Nordufer 20 \
43
+ 13353 Berlin \
44
+ Germany
45
+
46
+ ## package
47
+
48
+ Create a new release, including changelog rollover, project version bump, commit, tag
49
+ and push.
50
+
51
+ ## license
52
+
53
+ This package is licensed under the [MIT license](/LICENSE). All other software
54
+ components of the MEx project are open-sourced under the same license as well.
55
+
56
+ ## development
57
+
58
+ ### installation
59
+
60
+ - on unix, consider using pyenv https://github.com/pyenv/pyenv
61
+ - get pyenv `curl https://pyenv.run | bash`
62
+ - install 3.11 `pyenv install 3.11`
63
+ - switch version `pyenv global 3.11`
64
+ - run `make install`
65
+ - on windows, consider using pyenv-win https://pyenv-win.github.io/pyenv-win/
66
+ - follow https://pyenv-win.github.io/pyenv-win/#quick-start
67
+ - install 3.11 `pyenv install 3.11`
68
+ - switch version `pyenv global 3.11`
69
+ - run `.\mex.bat install`
70
+
71
+ ### linting and testing
72
+
73
+ - run all linters with `pdm lint`
74
+ - run only unit tests with `pdm unit`
75
+ - run unit and integration tests with `pdm test`
76
+
77
+ ### updating dependencies
78
+
79
+ - update boilerplate files with `cruft update`
80
+ - update global requirements in `requirements.txt` manually
81
+ - update git hooks with `pre-commit autoupdate`
82
+ - update package dependencies using `pdm update-all`
83
+ - update github actions in `.github/workflows/*.yml` manually
84
+
85
+ ### creating release
86
+
87
+ - run `pdm release RULE` to release a new version where RULE determines which part of
88
+ the version to update and is one of `major`, `minor`, `patch`.
89
+
90
+ ### container workflow
91
+
92
+ - build image with `make image`
93
+ - run directly using docker `make run`
94
+ - start with docker compose `make start`
95
+
96
+ ## commands
97
+
98
+ - run `pdm release VERSION` to release a new version where VERSION matches the regular
99
+ expression: `\d{1,4}\.\d{1,4}\.\d{1,4}`.
@@ -0,0 +1,178 @@
1
+ [project]
2
+ name = "mex-release"
3
+ version = "0.2.0"
4
+ description = "Create new release with `pdm release VERSION`"
5
+ authors = [
6
+ { name = "MEx Team", email = "mex@rki.de" },
7
+ ]
8
+ requires-python = "<3.13,>=3.11"
9
+ dependencies = [
10
+ "pdm>=2.13.2,<3.0",
11
+ ]
12
+
13
+ [project.readme]
14
+ file = "README.md"
15
+ content-type = "text/markdown"
16
+
17
+ [project.license]
18
+ file = "LICENSE"
19
+
20
+ [project.urls]
21
+ Repository = "https://github.com/robert-koch-institut/mex-release"
22
+
23
+ [project.optional-dependencies]
24
+ dev = [
25
+ "ipdb>=0.13.13,<1",
26
+ "mypy>=1.11.0,<2",
27
+ "ruff>=0.5.4,<1",
28
+ ]
29
+
30
+ [project.entry-points.pdm]
31
+ release = "release:release"
32
+
33
+ [tool.cruft]
34
+ template = "https://github.com/robert-koch-institut/mex-template"
35
+ skip = [
36
+ "CHANGELOG.md",
37
+ "mex",
38
+ "tests",
39
+ ]
40
+
41
+ [tool.ipdb]
42
+ context = 5
43
+
44
+ [tool.mypy]
45
+ python_version = "3.11"
46
+ show_error_codes = true
47
+ strict = true
48
+ plugins = [
49
+ "pydantic.mypy",
50
+ ]
51
+
52
+ [tool.pdm]
53
+ distribution = true
54
+
55
+ [tool.pdm.scripts.update-all]
56
+ cmd = "pdm update --group :all --update-all --save-compatible"
57
+
58
+ [tool.pdm.scripts.lock-all]
59
+ cmd = "pdm lock --group :all --python='==3.11.*'"
60
+
61
+ [tool.pdm.scripts.install-all]
62
+ cmd = "pdm install --group :all --frozen-lockfile"
63
+
64
+ [tool.pdm.scripts.export-all]
65
+ cmd = "pdm export --group :all --no-hashes -f requirements"
66
+
67
+ [tool.pdm.scripts.apidoc]
68
+ cmd = "pdm run sphinx-apidoc -f -o docs/source mex"
69
+
70
+ [tool.pdm.scripts.sphinx]
71
+ cmd = "pdm run sphinx-build -aE -b dirhtml docs docs/dist"
72
+
73
+ [tool.pdm.scripts.doc]
74
+ composite = [
75
+ "apidoc",
76
+ "sphinx",
77
+ ]
78
+
79
+ [tool.pdm.scripts.wheel]
80
+ cmd = "pdm build --no-sdist"
81
+
82
+ [tool.pdm.scripts.mypy-daemon]
83
+ cmd = "pdm run dmypy run --timeout 7200 -- mex"
84
+
85
+ [tool.pdm.scripts.lint]
86
+ cmd = "pre-commit run --all-files"
87
+
88
+ [tool.pdm.scripts.unit]
89
+ cmd = "pdm run pytest -m 'not integration'"
90
+
91
+ [tool.pdm.scripts.test]
92
+ cmd = "pdm run pytest --numprocesses=auto --dist=worksteal"
93
+
94
+ [tool.pdm.scripts.all]
95
+ composite = [
96
+ "install-all",
97
+ "lint",
98
+ "test",
99
+ "doc",
100
+ ]
101
+
102
+ [tool.pydantic-mypy]
103
+ warn_untyped_fields = true
104
+
105
+ [tool.pytest.ini_options]
106
+ addopts = [
107
+ "--verbose",
108
+ "--cov",
109
+ "--no-cov-on-fail",
110
+ "--cov-report=term-missing:skip-covered",
111
+ "--cov-fail-under=95",
112
+ "--cov-branch",
113
+ "--pdbcls=IPython.terminal.debugger:TerminalPdb",
114
+ "--random-order-bucket=global",
115
+ ]
116
+ markers = "integration: mark a test as integration test"
117
+
118
+ [tool.ruff]
119
+ fix = true
120
+ line-length = 88
121
+ show-fixes = true
122
+
123
+ [tool.ruff.format]
124
+ docstring-code-format = true
125
+
126
+ [tool.ruff.lint]
127
+ ignore = [
128
+ "D100",
129
+ "D104",
130
+ "D106",
131
+ "D203",
132
+ "D213",
133
+ "D406",
134
+ "D407",
135
+ "D413",
136
+ "N805",
137
+ "N815",
138
+ "RUF012",
139
+ ]
140
+ select = [
141
+ "A",
142
+ "B",
143
+ "C90",
144
+ "D",
145
+ "E",
146
+ "ERA",
147
+ "F",
148
+ "I",
149
+ "N",
150
+ "PERF",
151
+ "RET",
152
+ "RUF",
153
+ "S",
154
+ "T10",
155
+ "T20",
156
+ "UP",
157
+ "W",
158
+ ]
159
+
160
+ [tool.ruff.lint.per-file-ignores]
161
+ "tests/**" = [
162
+ "D101",
163
+ "D102",
164
+ "D103",
165
+ "D107",
166
+ "E501",
167
+ "N807",
168
+ "S101",
169
+ ]
170
+
171
+ [tool.ruff.lint.pydocstyle]
172
+ convention = "google"
173
+
174
+ [build-system]
175
+ requires = [
176
+ "pdm-backend==2.4.1",
177
+ ]
178
+ build-backend = "pdm.backend"
@@ -0,0 +1,147 @@
1
+ import argparse
2
+ import re
3
+ import subprocess
4
+ from datetime import date
5
+
6
+ from pdm import termui
7
+ from pdm.cli.commands.base import BaseCommand
8
+ from pdm.core import Core
9
+ from pdm.project import Project
10
+ from pdm.project.project_file import PyProject
11
+
12
+ CHANGELOG_TEMPLATE = """
13
+ ## [Unreleased]
14
+
15
+ ### Added
16
+
17
+ ### Changes
18
+
19
+ ### Deprecated
20
+
21
+ ### Removed
22
+
23
+ ### Fixed
24
+
25
+ ### Security
26
+
27
+ ## [{version}] - {date}
28
+ """
29
+
30
+
31
+ class ReleaseCommand(BaseCommand):
32
+ """Set project version to the given version."""
33
+
34
+ def add_arguments(self, parser: argparse.ArgumentParser) -> None:
35
+ """Manipulate the argument parser to add more arguments."""
36
+ parser.add_argument(
37
+ "bump",
38
+ choices=("major", "minor", "patch"),
39
+ default="patch",
40
+ help="part of the project version to update",
41
+ )
42
+
43
+ def handle(self, project: Project, options: argparse.Namespace) -> None:
44
+ """Execute the release command."""
45
+ releaser = Releaser(project.pyproject, options.bump)
46
+ releaser.release()
47
+
48
+
49
+ class Releaser:
50
+ """Wrap the release functionality in a single object."""
51
+
52
+ def __init__(self, pyproject: PyProject, bump: str) -> None:
53
+ """Create a new releaser instance."""
54
+ self.bump = bump
55
+ self.pyproject = pyproject
56
+
57
+ def run(self, *args: str) -> str:
58
+ """Run a command as subproccess, first print it, later print the output."""
59
+ self.pyproject.ui.echo(" ".join(args))
60
+ # use noqa because we check user input (bump) and all other args are hard
61
+ # coded
62
+ stdout = subprocess.check_output(args).decode("utf-8") # noqa: S603
63
+ self.pyproject.ui.echo(
64
+ stdout,
65
+ verbosity=termui.Verbosity.NORMAL,
66
+ )
67
+ return stdout.strip()
68
+
69
+ def check_working_tree(self) -> None:
70
+ """Only continue if working tree is empty."""
71
+ if self.run("git", "status", "--short"):
72
+ raise RuntimeError(
73
+ "Working tree is dirty. Can only release clean working tree."
74
+ )
75
+
76
+ def check_default_branch(self) -> None:
77
+ """Only continue if default branch is checked out."""
78
+ git_branch = self.run("git", "rev-parse", "--abbrev-ref", "HEAD")
79
+ git_origin_branches = self.run("git", "remote", "show", "origin")
80
+ git_default_branch = re.findall(
81
+ r"HEAD branch: (\S+)", str(git_origin_branches)
82
+ )[0]
83
+ if git_branch != git_default_branch:
84
+ raise RuntimeError(
85
+ "Not on default branch. Can only release on default branch."
86
+ )
87
+
88
+ def check_version_string(self) -> None:
89
+ """Validate the version string to format `0.3.14`."""
90
+ if not re.match(
91
+ r"\d{1,4}\.\d{1,4}\.\d{1,4}", self.pyproject.metadata["version"]
92
+ ):
93
+ raise RuntimeError("Current version string does not match expected format.")
94
+
95
+ def release(self) -> None:
96
+ """Execute the release command."""
97
+ self.check_working_tree()
98
+ self.check_default_branch()
99
+ self.check_version_string()
100
+
101
+ # update project version in toml
102
+ major, minor, patch = self.pyproject.metadata["version"].split(".")
103
+ if self.bump == "major":
104
+ new_version = f"{int(major) + 1}.0.0"
105
+ elif self.bump == "minor":
106
+ new_version = f"{major}.{int(minor) + 1}.0"
107
+ elif self.bump == "patch":
108
+ new_version = f"{major}.{minor}.{int(patch) + 1}"
109
+ else:
110
+ raise Exception("Unexpected bump value.")
111
+ self.pyproject.metadata["version"] = new_version
112
+ self.pyproject.write()
113
+
114
+ # rollover changelog sections
115
+ with open("CHANGELOG.md") as fh:
116
+ changelog = fh.read()
117
+ # remove empty subsections
118
+ changelog = re.sub(r"^### [A-Za-z]+\s+(?=#)", "", changelog, flags=re.MULTILINE)
119
+ # add a new unreleased section
120
+ changelog = changelog.replace(
121
+ "\n## [Unreleased]\n",
122
+ CHANGELOG_TEMPLATE.format(version=new_version, date=date.today()),
123
+ )
124
+ with open("CHANGELOG.md", "w") as fh:
125
+ fh.write(changelog)
126
+ self.pyproject.ui.echo(
127
+ "Changes are written to [success]CHANGELOG.md[/].",
128
+ verbosity=termui.Verbosity.NORMAL,
129
+ )
130
+
131
+ # commit, tag and push
132
+ self.run(
133
+ "git",
134
+ "commit",
135
+ "-m",
136
+ f"bump version to {new_version}",
137
+ "CHANGELOG.md",
138
+ "pyproject.toml",
139
+ )
140
+ self.run("git", "tag", f"{new_version}")
141
+ self.run("git", "push")
142
+ self.run("git", "push", "--tags")
143
+
144
+
145
+ def release(core: Core) -> None:
146
+ """Register the release command as a pdm command."""
147
+ core.register_command(ReleaseCommand, "release")