autopub 1.0.0a14__tar.gz → 1.0.0a16__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {autopub-1.0.0a14 → autopub-1.0.0a16}/PKG-INFO +1 -1
- {autopub-1.0.0a14 → autopub-1.0.0a16}/autopub/__init__.py +26 -30
- {autopub-1.0.0a14 → autopub-1.0.0a16}/autopub/cli/__init__.py +3 -1
- {autopub-1.0.0a14 → autopub-1.0.0a16}/autopub/plugins/__init__.py +21 -3
- {autopub-1.0.0a14 → autopub-1.0.0a16}/autopub/plugins/bump_version.py +11 -9
- {autopub-1.0.0a14 → autopub-1.0.0a16}/autopub/plugins/git.py +5 -3
- {autopub-1.0.0a14 → autopub-1.0.0a16}/autopub/plugins/update_changelog.py +7 -3
- autopub-1.0.0a16/autopub/types.py +33 -0
- {autopub-1.0.0a14 → autopub-1.0.0a16}/pyproject.toml +2 -1
- autopub-1.0.0a14/autopub/types.py +0 -11
- {autopub-1.0.0a14 → autopub-1.0.0a16}/LICENSE +0 -0
- {autopub-1.0.0a14 → autopub-1.0.0a16}/README.md +0 -0
- {autopub-1.0.0a14 → autopub-1.0.0a16}/autopub/cli/plugins.py +0 -0
- {autopub-1.0.0a14 → autopub-1.0.0a16}/autopub/exceptions.py +0 -0
- {autopub-1.0.0a14 → autopub-1.0.0a16}/autopub/plugins/pdm.py +0 -0
- {autopub-1.0.0a14 → autopub-1.0.0a16}/autopub/plugins/poetry.py +0 -0
- {autopub-1.0.0a14 → autopub-1.0.0a16}/autopub/py.typed +0 -0
@@ -18,7 +18,10 @@ from autopub.exceptions import (
|
|
18
18
|
ReleaseTypeInvalid,
|
19
19
|
ReleaseTypeMissing,
|
20
20
|
)
|
21
|
-
from autopub.plugins import
|
21
|
+
from autopub.plugins import (
|
22
|
+
AutopubPackageManagerPlugin,
|
23
|
+
AutopubPlugin,
|
24
|
+
)
|
22
25
|
from autopub.types import ReleaseInfo
|
23
26
|
|
24
27
|
|
@@ -41,26 +44,22 @@ class Autopub:
|
|
41
44
|
return hashlib.sha256(self.release_notes.encode("utf-8")).hexdigest()
|
42
45
|
|
43
46
|
@property
|
44
|
-
def
|
45
|
-
return Path(".autopub") / "
|
47
|
+
def release_info_file(self) -> Path:
|
48
|
+
return Path(".autopub") / "release_info.json"
|
46
49
|
|
47
50
|
@property
|
48
|
-
def
|
49
|
-
if not self.
|
51
|
+
def release_info(self) -> ReleaseInfo:
|
52
|
+
if not self.release_info_file.exists():
|
50
53
|
raise ArtifactNotFound()
|
51
54
|
|
52
|
-
|
55
|
+
release_info = json.loads(self.release_info_file.read_text())
|
53
56
|
|
54
|
-
if
|
57
|
+
if release_info["hash"] != self.release_file_hash:
|
55
58
|
raise ArtifactHashMismatch()
|
56
59
|
|
57
|
-
return ReleaseInfo(
|
58
|
-
release_type=release_data["release_type"],
|
59
|
-
release_notes=release_data["release_notes"],
|
60
|
-
additional_info=release_data["plugin_data"],
|
61
|
-
)
|
60
|
+
return ReleaseInfo.from_dict(release_info)
|
62
61
|
|
63
|
-
def check(self) ->
|
62
|
+
def check(self) -> None:
|
64
63
|
release_file = Path(self.RELEASE_FILE_PATH)
|
65
64
|
|
66
65
|
if not release_file.exists():
|
@@ -76,9 +75,10 @@ class Autopub:
|
|
76
75
|
for plugin in self.plugins:
|
77
76
|
plugin.on_release_notes_valid(release_info)
|
78
77
|
|
79
|
-
self.
|
78
|
+
for plugin in self.plugins:
|
79
|
+
plugin.post_check(release_info)
|
80
80
|
|
81
|
-
|
81
|
+
self._write_artifact(release_info)
|
82
82
|
|
83
83
|
def build(self) -> None:
|
84
84
|
if not any(
|
@@ -91,21 +91,21 @@ class Autopub:
|
|
91
91
|
plugin.build()
|
92
92
|
|
93
93
|
def prepare(self) -> None:
|
94
|
-
|
95
|
-
plugin.prepare(self.release_data)
|
94
|
+
release_info = self.release_info
|
96
95
|
|
97
|
-
self.
|
96
|
+
for plugin in self.plugins:
|
97
|
+
plugin.prepare(release_info)
|
98
98
|
|
99
99
|
for plugin in self.plugins:
|
100
|
-
plugin.post_prepare(
|
100
|
+
plugin.post_prepare(release_info)
|
101
101
|
|
102
|
-
self._write_artifact(
|
102
|
+
self._write_artifact(release_info)
|
103
103
|
|
104
104
|
def _delete_release_file(self) -> None:
|
105
105
|
self.release_file.unlink(missing_ok=True)
|
106
106
|
|
107
107
|
def publish(self, repository: str | None = None) -> None:
|
108
|
-
release_info = self.
|
108
|
+
release_info = self.release_info
|
109
109
|
|
110
110
|
for plugin in self.plugins:
|
111
111
|
# TODO: maybe pass release info to publish method?
|
@@ -119,18 +119,12 @@ class Autopub:
|
|
119
119
|
|
120
120
|
def _write_artifact(self, release_info: ReleaseInfo) -> None:
|
121
121
|
data = {
|
122
|
+
**release_info.dict(),
|
122
123
|
"hash": self.release_file_hash,
|
123
|
-
"release_type": release_info.release_type,
|
124
|
-
"release_notes": release_info.release_notes,
|
125
|
-
"plugin_data": {
|
126
|
-
key: value
|
127
|
-
for plugin in self.plugins
|
128
|
-
for key, value in plugin.data.items()
|
129
|
-
},
|
130
124
|
}
|
131
125
|
|
132
|
-
self.
|
133
|
-
self.
|
126
|
+
self.release_info_file.parent.mkdir(exist_ok=True)
|
127
|
+
self.release_info_file.write_text(json.dumps(data))
|
134
128
|
|
135
129
|
def _deprecated_load(self, release_notes: str) -> ReleaseInfo:
|
136
130
|
# supports loading of old release notes format, which is
|
@@ -178,6 +172,8 @@ class Autopub:
|
|
178
172
|
release_type=release_type,
|
179
173
|
release_notes=post.content,
|
180
174
|
additional_info=data,
|
175
|
+
version=None,
|
176
|
+
previous_version=None,
|
181
177
|
)
|
182
178
|
|
183
179
|
def _validate_release_notes(self, release_notes: str) -> ReleaseInfo:
|
@@ -29,12 +29,14 @@ def check():
|
|
29
29
|
autopub = Autopub(plugins=find_plugins(state["plugins"]))
|
30
30
|
|
31
31
|
try:
|
32
|
-
|
32
|
+
autopub.check()
|
33
33
|
except AutopubException as e:
|
34
34
|
rich.print(Panel.fit(f"[red]{e.message}"))
|
35
35
|
|
36
36
|
raise typer.Exit(1) from e
|
37
37
|
else:
|
38
|
+
release_info = autopub.release_info
|
39
|
+
|
38
40
|
rich.print(
|
39
41
|
Padding(
|
40
42
|
Group(
|
@@ -17,25 +17,43 @@ class AutopubPlugin:
|
|
17
17
|
except subprocess.CalledProcessError as e:
|
18
18
|
raise CommandFailed(command=command, returncode=e.returncode) from e
|
19
19
|
|
20
|
+
def post_check(self, release_info: ReleaseInfo) -> None: # pragma: no cover
|
21
|
+
...
|
22
|
+
|
20
23
|
def prepare(self, release_info: ReleaseInfo) -> None: # pragma: no cover
|
21
24
|
...
|
22
25
|
|
23
26
|
def post_prepare(self, release_info: ReleaseInfo) -> None: # pragma: no cover
|
24
27
|
...
|
25
28
|
|
26
|
-
def validate_release_notes(
|
29
|
+
def validate_release_notes(
|
30
|
+
self, release_info: ReleaseInfo
|
31
|
+
) -> None: # pragma: no cover
|
27
32
|
...
|
28
33
|
|
29
|
-
def on_release_notes_valid(
|
34
|
+
def on_release_notes_valid(
|
35
|
+
self, release_info: ReleaseInfo
|
36
|
+
) -> None: # pragma: no cover
|
30
37
|
...
|
31
38
|
|
32
|
-
def on_release_notes_invalid(
|
39
|
+
def on_release_notes_invalid(
|
40
|
+
self, exception: AutopubException
|
41
|
+
) -> None: # pragma: no cover
|
33
42
|
...
|
34
43
|
|
35
44
|
def post_publish(self, release_info: ReleaseInfo) -> None: # pragma: no cover
|
36
45
|
...
|
37
46
|
|
38
47
|
|
48
|
+
@runtime_checkable
|
49
|
+
class AutopubBumpVersionPlugin(Protocol):
|
50
|
+
new_version: str
|
51
|
+
current_version: str
|
52
|
+
|
53
|
+
def post_check(self, release_info: ReleaseInfo) -> None: # pragma: no cover
|
54
|
+
...
|
55
|
+
|
56
|
+
|
39
57
|
@runtime_checkable
|
40
58
|
class AutopubPackageManagerPlugin(Protocol):
|
41
59
|
def build(self) -> None: # pragma: no cover
|
@@ -5,11 +5,14 @@ import pathlib
|
|
5
5
|
import tomlkit
|
6
6
|
from dunamai import Version
|
7
7
|
|
8
|
-
from autopub.plugins import AutopubPlugin
|
8
|
+
from autopub.plugins import AutopubBumpVersionPlugin, AutopubPlugin
|
9
9
|
from autopub.types import ReleaseInfo
|
10
10
|
|
11
11
|
|
12
|
-
class BumpVersionPlugin(AutopubPlugin):
|
12
|
+
class BumpVersionPlugin(AutopubBumpVersionPlugin, AutopubPlugin):
|
13
|
+
current_version: str
|
14
|
+
new_version: str
|
15
|
+
|
13
16
|
@property
|
14
17
|
def pyproject_config(self) -> tomlkit.TOMLDocument:
|
15
18
|
content = pathlib.Path("pyproject.toml").read_text()
|
@@ -28,17 +31,16 @@ class BumpVersionPlugin(AutopubPlugin):
|
|
28
31
|
except KeyError:
|
29
32
|
config["project"]["version"] = new_version # type: ignore
|
30
33
|
|
31
|
-
def
|
34
|
+
def post_check(self, release_info: ReleaseInfo) -> None:
|
32
35
|
config = self.pyproject_config
|
33
36
|
|
34
|
-
version = Version(self._get_version(config))
|
35
|
-
|
36
37
|
bump_type = {"major": 0, "minor": 1, "patch": 2}[release_info.release_type]
|
37
|
-
new_version = version.bump(bump_type).serialize()
|
38
38
|
|
39
|
-
|
40
|
-
|
39
|
+
version = Version(self._get_version(config))
|
40
|
+
|
41
|
+
self.previous_version = str(version)
|
42
|
+
self.new_version = version.bump(bump_type).serialize()
|
41
43
|
|
42
|
-
self._update_version(config, new_version)
|
44
|
+
self._update_version(config, self.new_version)
|
43
45
|
|
44
46
|
pathlib.Path("pyproject.toml").write_text(tomlkit.dumps(config)) # type: ignore
|
@@ -6,16 +6,18 @@ from autopub.types import ReleaseInfo
|
|
6
6
|
|
7
7
|
class GitPlugin(AutopubPlugin):
|
8
8
|
def post_publish(self, release_info: ReleaseInfo) -> None:
|
9
|
-
|
9
|
+
assert release_info.version is not None
|
10
|
+
|
11
|
+
tag_name = release_info.version
|
10
12
|
|
11
13
|
self.run_command(["git", "config", "--global", "user.email", "autopub@autopub"])
|
12
14
|
self.run_command(["git", "config", "--global", "user.name", "autopub"])
|
13
15
|
|
14
|
-
self.run_command(["git", "tag",
|
16
|
+
self.run_command(["git", "tag", tag_name])
|
15
17
|
|
16
18
|
# TODO: config?
|
17
19
|
self.run_command(["git", "rm", "RELEASE.md"])
|
18
20
|
self.run_command(["git", "add", "--all", "--", ":!main/.autopub"])
|
19
21
|
self.run_command(["git", "commit", "-m", "🤖 autopub publish"])
|
20
22
|
self.run_command(["git", "push"])
|
21
|
-
self.run_command(["git", "push", "origin",
|
23
|
+
self.run_command(["git", "push", "origin", tag_name])
|
@@ -17,8 +17,6 @@ class UpdateChangelogPlugin(AutopubPlugin):
|
|
17
17
|
return Path("CHANGELOG.md")
|
18
18
|
|
19
19
|
def post_prepare(self, release_info: ReleaseInfo) -> None:
|
20
|
-
assert release_info.additional_info["new_version"]
|
21
|
-
|
22
20
|
if not self.changelog_file.exists():
|
23
21
|
self.changelog_file.write_text(f"CHANGELOG\n{CHANGELOG_HEADER}\n\n")
|
24
22
|
|
@@ -37,7 +35,9 @@ class UpdateChangelogPlugin(AutopubPlugin):
|
|
37
35
|
header = lines[: index + 1]
|
38
36
|
break
|
39
37
|
|
40
|
-
new_version = release_info.
|
38
|
+
new_version = release_info.version
|
39
|
+
|
40
|
+
assert new_version is not None
|
41
41
|
|
42
42
|
with self.changelog_file.open("w") as f:
|
43
43
|
f.write("\n".join(header))
|
@@ -48,5 +48,9 @@ class UpdateChangelogPlugin(AutopubPlugin):
|
|
48
48
|
f.write(f"\n{new_version_header}\n")
|
49
49
|
f.write(f"{VERSION_HEADER * len(new_version_header)}\n\n")
|
50
50
|
f.write(release_info.release_notes)
|
51
|
+
|
52
|
+
for line in release_info.additional_release_notes:
|
53
|
+
f.write(f"\n\n{line}")
|
54
|
+
|
51
55
|
f.write("\n")
|
52
56
|
f.write("\n".join(old_changelog_data))
|
@@ -0,0 +1,33 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
import dataclasses
|
4
|
+
from typing import Any
|
5
|
+
|
6
|
+
from typing_extensions import Self
|
7
|
+
|
8
|
+
|
9
|
+
@dataclasses.dataclass(kw_only=True)
|
10
|
+
class ReleaseInfo:
|
11
|
+
"""Release information."""
|
12
|
+
|
13
|
+
release_type: str
|
14
|
+
release_notes: str
|
15
|
+
additional_info: dict[str, Any] = dataclasses.field(default_factory=dict)
|
16
|
+
additional_release_notes: list[str] = dataclasses.field(default_factory=list)
|
17
|
+
version: str | None = None
|
18
|
+
previous_version: str | None = None
|
19
|
+
|
20
|
+
def dict(self) -> dict[str, Any]:
|
21
|
+
"""Return a dictionary representation of the release info."""
|
22
|
+
return dataclasses.asdict(self)
|
23
|
+
|
24
|
+
@classmethod
|
25
|
+
def from_dict(cls, data: dict[str, Any]) -> Self:
|
26
|
+
return cls(
|
27
|
+
release_type=data["release_type"],
|
28
|
+
release_notes=data["release_notes"],
|
29
|
+
additional_info=data["additional_info"],
|
30
|
+
additional_release_notes=data["additional_release_notes"],
|
31
|
+
version=data["version"],
|
32
|
+
previous_version=data["previous_version"],
|
33
|
+
)
|
@@ -3,7 +3,7 @@ requires-python = ">=3.8"
|
|
3
3
|
|
4
4
|
[tool.poetry]
|
5
5
|
name = "autopub"
|
6
|
-
version = "1.0.0-alpha.
|
6
|
+
version = "1.0.0-alpha.16"
|
7
7
|
description = "Automatic package release upon pull request merge"
|
8
8
|
authors = ["Justin Mayer <entroP@gmail.com>", "Patrick Arminio <patrick.arminio@gmail.com>"]
|
9
9
|
license = "AGPL-3.0"
|
@@ -66,6 +66,7 @@ autopub = "autopub.cli:app"
|
|
66
66
|
|
67
67
|
[tool.poetry.group.dev.dependencies]
|
68
68
|
pytest-cov = "^4.1.0"
|
69
|
+
pytest-mock = "^3.12.0"
|
69
70
|
|
70
71
|
[tool.autopub]
|
71
72
|
project-name = "AutoPub"
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|