python-semantic-release 9.8.4__py3-none-any.whl → 9.8.6__py3-none-any.whl
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.
- {python_semantic_release-9.8.4.dist-info → python_semantic_release-9.8.6.dist-info}/METADATA +1 -1
- {python_semantic_release-9.8.4.dist-info → python_semantic_release-9.8.6.dist-info}/RECORD +11 -11
- semantic_release/__init__.py +1 -1
- semantic_release/changelog/release_history.py +44 -39
- semantic_release/cli/cli_context.py +29 -9
- semantic_release/cli/commands/version.py +29 -10
- {python_semantic_release-9.8.4.dist-info → python_semantic_release-9.8.6.dist-info}/AUTHORS.rst +0 -0
- {python_semantic_release-9.8.4.dist-info → python_semantic_release-9.8.6.dist-info}/LICENSE +0 -0
- {python_semantic_release-9.8.4.dist-info → python_semantic_release-9.8.6.dist-info}/WHEEL +0 -0
- {python_semantic_release-9.8.4.dist-info → python_semantic_release-9.8.6.dist-info}/entry_points.txt +0 -0
- {python_semantic_release-9.8.4.dist-info → python_semantic_release-9.8.6.dist-info}/top_level.txt +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
semantic_release/__init__.py,sha256=
|
|
1
|
+
semantic_release/__init__.py,sha256=dK5qhd8q7ljShz7YRlOlqV3-FOjS5Tac2HMNFOtIj5k,1228
|
|
2
2
|
semantic_release/__main__.py,sha256=blPn7CMpuSe4Z-GBIDv0QA0OEDTMGU-7edsLRkkhPR4,120
|
|
3
3
|
semantic_release/const.py,sha256=Z1o2QNh60wSLeF-_1TemMBjU3ZXbV0XghnUFsbTVfOs,831
|
|
4
4
|
semantic_release/enums.py,sha256=D5B_reQGGKQQT22HO5PUtvn2Bok3fkht6TfJtXkmAUg,1020
|
|
@@ -7,11 +7,11 @@ semantic_release/gitproject.py,sha256=izWc4NLdUzAwxGG_fJeqqHW9ivSrPcWBzSaOijQx4f
|
|
|
7
7
|
semantic_release/helpers.py,sha256=d1jOX0SNyqPc_3wr14xR25FfpqhMd4Ev7MNBOWlScc0,5581
|
|
8
8
|
semantic_release/changelog/__init__.py,sha256=Bg6Xe5Vt32rWoMscW-hd4sUwiZqzWmsg4CD1EhMesMY,262
|
|
9
9
|
semantic_release/changelog/context.py,sha256=8cbOv9cB9Ji7xjRn4-YUUHBfg9LLfSwmmXuZpqEmvns,1653
|
|
10
|
-
semantic_release/changelog/release_history.py,sha256=
|
|
10
|
+
semantic_release/changelog/release_history.py,sha256=9gJxqOKPF9HjmOdXW-k-dWbe2YGWxqZEOWSSef-qwoE,7050
|
|
11
11
|
semantic_release/changelog/template.py,sha256=JqZcjdozM9-059Sa8PfiHxYNeyZFa0jxk_beyRLv5sU,4640
|
|
12
12
|
semantic_release/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
13
|
semantic_release/cli/changelog_writer.py,sha256=Ga8QAq12kUD-fWWlrFoQCpn1pOzZmHnaCeZfFbBytFo,5027
|
|
14
|
-
semantic_release/cli/cli_context.py,sha256=
|
|
14
|
+
semantic_release/cli/cli_context.py,sha256=23eyV6KWIpUckUSWILEd7t9dixp-QCY5-kGZnyucEYY,4114
|
|
15
15
|
semantic_release/cli/config.py,sha256=NAKOqLAc8NV0oL9XxAUPz2FWwS89Bjz8aKSCsRmQsvw,23661
|
|
16
16
|
semantic_release/cli/const.py,sha256=S8oNNpSaKdZxcAs7PAKEjQHic0czoJBGd7XHo57FOzw,39
|
|
17
17
|
semantic_release/cli/github_actions_output.py,sha256=Wy4jEIpSFgoMyJqq4FD7scIpgovivutFLZ7Fs4y2CUY,2110
|
|
@@ -22,7 +22,7 @@ semantic_release/cli/commands/changelog.py,sha256=zincrvCBwMb7S3K3udRcArtQCuGkre
|
|
|
22
22
|
semantic_release/cli/commands/generate_config.py,sha256=2xZOu3NpyhBp0pWr7d8ugKl_kjqQgpSsSMHq5wHTfrE,1699
|
|
23
23
|
semantic_release/cli/commands/main.py,sha256=kqO8bZw9Nv6T5QkIl53zzmH2rd4LuLoA8agweH0VYPY,4022
|
|
24
24
|
semantic_release/cli/commands/publish.py,sha256=SZQlIewvqyIC14dkIIVVFetE0tPsKbO1cUyxnZsicrw,2845
|
|
25
|
-
semantic_release/cli/commands/version.py,sha256=
|
|
25
|
+
semantic_release/cli/commands/version.py,sha256=fRdzfPhWjS7_ssgNRQ2-VJZVePofy8plBXRbhFkD_P0,24316
|
|
26
26
|
semantic_release/commit_parser/__init__.py,sha256=cv5HFBdw7OJd4Laj4Ex8ZZ5Tml8GwXgQcXW6Pasr2Ao,615
|
|
27
27
|
semantic_release/commit_parser/_base.py,sha256=t-Z9ALgAe7aZpYXz1mk3Fe-uAvipgKdNrq4Okg_WW9c,3026
|
|
28
28
|
semantic_release/commit_parser/angular.py,sha256=ERWeTBTFNIBOaTIopY4Vff0KbeFwrSQWbADe3smVW-8,4579
|
|
@@ -47,10 +47,10 @@ semantic_release/version/algorithm.py,sha256=ofx_bIWq6ptJVr-ekI11IzxzDEctDKFiVwa
|
|
|
47
47
|
semantic_release/version/declaration.py,sha256=f6Ld7hIhrqvDrRBapJHr-KDimuyo-4IG8009Zu9BIgU,7357
|
|
48
48
|
semantic_release/version/translator.py,sha256=P1noIsVBn8u6zNOFjG0xKYOWapxqf_PHSMvMeLJ9kXg,3050
|
|
49
49
|
semantic_release/version/version.py,sha256=6PCtSbLP88U1daoxnCwHc--YguZo4waGNLqJ5JfeczE,14175
|
|
50
|
-
python_semantic_release-9.8.
|
|
51
|
-
python_semantic_release-9.8.
|
|
52
|
-
python_semantic_release-9.8.
|
|
53
|
-
python_semantic_release-9.8.
|
|
54
|
-
python_semantic_release-9.8.
|
|
55
|
-
python_semantic_release-9.8.
|
|
56
|
-
python_semantic_release-9.8.
|
|
50
|
+
python_semantic_release-9.8.6.dist-info/AUTHORS.rst,sha256=XOReVvpymEFUPsS2QPH97jlfJBVrxwS2eu8-jVAe4gk,230
|
|
51
|
+
python_semantic_release-9.8.6.dist-info/LICENSE,sha256=NE85nszX252sdQdu0xgS9qwfYES0k8qS6gW3uO4jRGE,1083
|
|
52
|
+
python_semantic_release-9.8.6.dist-info/METADATA,sha256=i1R195z7bs33vk2LYi00R9f2kEDS9X_CLUF8tFBTaQM,5404
|
|
53
|
+
python_semantic_release-9.8.6.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
54
|
+
python_semantic_release-9.8.6.dist-info/entry_points.txt,sha256=6bS6euSagjerp7onDtfI9_ZpczWreZF3gjHfGAegkbo,123
|
|
55
|
+
python_semantic_release-9.8.6.dist-info/top_level.txt,sha256=qYA24nyg3eP-ti5UW7Vuj2aXVmM0wqVHx4mREdRZNAA,17
|
|
56
|
+
python_semantic_release-9.8.6.dist-info/RECORD,,
|
semantic_release/__init__.py
CHANGED
|
@@ -41,6 +41,13 @@ class ReleaseHistory:
|
|
|
41
41
|
unreleased: dict[str, list[ParseResult]] = defaultdict(list)
|
|
42
42
|
released: dict[Version, Release] = {}
|
|
43
43
|
|
|
44
|
+
# Performance optimization: create a mapping of tag sha to version
|
|
45
|
+
# so we can quickly look up the version for a given commit based on sha
|
|
46
|
+
tag_sha_2_version_lookup = {
|
|
47
|
+
tag.commit.hexsha: (tag, version)
|
|
48
|
+
for tag, version in all_git_tags_and_versions
|
|
49
|
+
}
|
|
50
|
+
|
|
44
51
|
# Strategy:
|
|
45
52
|
# Loop through commits in history, parsing as we go.
|
|
46
53
|
# Add these commits to `unreleased` as a key-value mapping
|
|
@@ -54,7 +61,7 @@ class ReleaseHistory:
|
|
|
54
61
|
is_commit_released = False
|
|
55
62
|
the_version: Version | None = None
|
|
56
63
|
|
|
57
|
-
for commit in repo.iter_commits():
|
|
64
|
+
for commit in repo.iter_commits("HEAD", topo_order=True):
|
|
58
65
|
# mypy will be happy if we make this an explicit string
|
|
59
66
|
commit_message = str(commit.message)
|
|
60
67
|
|
|
@@ -64,46 +71,44 @@ class ReleaseHistory:
|
|
|
64
71
|
)
|
|
65
72
|
log.debug("commit has type %s", commit_type)
|
|
66
73
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
tag.object.committed_date, tz=_tz
|
|
95
|
-
)
|
|
96
|
-
|
|
97
|
-
release = Release(
|
|
98
|
-
tagger=tagger,
|
|
99
|
-
committer=committer,
|
|
100
|
-
tagged_date=tagged_date,
|
|
101
|
-
elements=defaultdict(list),
|
|
102
|
-
version=the_version,
|
|
74
|
+
log.debug("checking if commit %s matches any tags", commit.hexsha)
|
|
75
|
+
t_v = tag_sha_2_version_lookup.get(commit.hexsha, None)
|
|
76
|
+
|
|
77
|
+
if t_v is None:
|
|
78
|
+
log.debug("no tags correspond to commit %s", commit.hexsha)
|
|
79
|
+
else:
|
|
80
|
+
# Unpack the tuple (overriding the current version)
|
|
81
|
+
tag, the_version = t_v
|
|
82
|
+
# we have found the latest commit introduced by this tag
|
|
83
|
+
# so we create a new Release entry
|
|
84
|
+
log.debug("found commit %s for tag %s", commit.hexsha, tag.name)
|
|
85
|
+
is_commit_released = True
|
|
86
|
+
|
|
87
|
+
# tag.object is a Commit if the tag is lightweight, otherwise
|
|
88
|
+
# it is a TagObject with additional metadata about the tag
|
|
89
|
+
if isinstance(tag.object, TagObject):
|
|
90
|
+
tagger = tag.object.tagger
|
|
91
|
+
committer = tag.object.tagger.committer()
|
|
92
|
+
_tz = timezone(timedelta(seconds=-1 * tag.object.tagger_tz_offset))
|
|
93
|
+
tagged_date = datetime.fromtimestamp(tag.object.tagged_date, tz=_tz)
|
|
94
|
+
else:
|
|
95
|
+
# For some reason, sometimes tag.object is a Commit
|
|
96
|
+
tagger = tag.object.author
|
|
97
|
+
committer = tag.object.author
|
|
98
|
+
_tz = timezone(timedelta(seconds=-1 * tag.object.author_tz_offset))
|
|
99
|
+
tagged_date = datetime.fromtimestamp(
|
|
100
|
+
tag.object.committed_date, tz=_tz
|
|
103
101
|
)
|
|
104
102
|
|
|
105
|
-
|
|
106
|
-
|
|
103
|
+
release = Release(
|
|
104
|
+
tagger=tagger,
|
|
105
|
+
committer=committer,
|
|
106
|
+
tagged_date=tagged_date,
|
|
107
|
+
elements=defaultdict(list),
|
|
108
|
+
version=the_version,
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
released.setdefault(the_version, release)
|
|
107
112
|
|
|
108
113
|
if any(pat.match(commit_message) for pat in exclude_commit_patterns):
|
|
109
114
|
log.debug(
|
|
@@ -34,10 +34,17 @@ class CliContextObj:
|
|
|
34
34
|
logger: logging.Logger,
|
|
35
35
|
global_opts: GlobalCommandLineOptions,
|
|
36
36
|
) -> None:
|
|
37
|
-
self._runtime_ctx: RuntimeContext | None = None
|
|
38
37
|
self.ctx = ctx
|
|
39
38
|
self.logger = logger
|
|
40
39
|
self.global_opts = global_opts
|
|
40
|
+
self._raw_config: RawConfig | None = None
|
|
41
|
+
self._runtime_ctx: RuntimeContext | None = None
|
|
42
|
+
|
|
43
|
+
@property
|
|
44
|
+
def raw_config(self) -> RawConfig:
|
|
45
|
+
if self._raw_config is None:
|
|
46
|
+
self._raw_config = self._init_raw_config()
|
|
47
|
+
return self._raw_config
|
|
41
48
|
|
|
42
49
|
@property
|
|
43
50
|
def runtime_ctx(self) -> RuntimeContext:
|
|
@@ -49,7 +56,7 @@ class CliContextObj:
|
|
|
49
56
|
self._runtime_ctx = self._init_runtime_ctx()
|
|
50
57
|
return self._runtime_ctx
|
|
51
58
|
|
|
52
|
-
def
|
|
59
|
+
def _init_raw_config(self) -> RawConfig:
|
|
53
60
|
config_path = Path(self.global_opts.config_file)
|
|
54
61
|
conf_file_exists = config_path.exists()
|
|
55
62
|
was_conf_file_user_provided = bool(
|
|
@@ -60,6 +67,7 @@ class CliContextObj:
|
|
|
60
67
|
)
|
|
61
68
|
)
|
|
62
69
|
|
|
70
|
+
# TODO: Evaluate Exeception catches
|
|
63
71
|
try:
|
|
64
72
|
if was_conf_file_user_provided and not conf_file_exists:
|
|
65
73
|
raise FileNotFoundError( # noqa: TRY301
|
|
@@ -74,24 +82,36 @@ class CliContextObj:
|
|
|
74
82
|
"configuration empty, falling back to default configuration"
|
|
75
83
|
)
|
|
76
84
|
|
|
77
|
-
|
|
85
|
+
return RawConfig.model_validate(config_obj)
|
|
86
|
+
except FileNotFoundError as exc:
|
|
87
|
+
click.echo(str(exc), err=True)
|
|
88
|
+
self.ctx.exit(2)
|
|
89
|
+
except (
|
|
90
|
+
ValidationError,
|
|
91
|
+
InvalidConfiguration,
|
|
92
|
+
InvalidGitRepositoryError,
|
|
93
|
+
) as exc:
|
|
94
|
+
click.echo(str(exc), err=True)
|
|
95
|
+
self.ctx.exit(1)
|
|
96
|
+
|
|
97
|
+
def _init_runtime_ctx(self) -> RuntimeContext:
|
|
98
|
+
# TODO: Evaluate Exception catches
|
|
99
|
+
try:
|
|
78
100
|
runtime = RuntimeContext.from_raw_config(
|
|
79
|
-
raw_config,
|
|
101
|
+
self.raw_config,
|
|
80
102
|
global_cli_options=self.global_opts,
|
|
81
103
|
)
|
|
82
|
-
except
|
|
104
|
+
except NotAReleaseBranch as exc:
|
|
83
105
|
rprint(f"[bold {'red' if self.global_opts.strict else 'orange1'}]{exc!s}")
|
|
84
106
|
# If not strict, exit 0 so other processes can continue. For example, in
|
|
85
107
|
# multibranch CI it might be desirable to run a non-release branch's pipeline
|
|
86
108
|
# without specifying conditional execution of PSR based on branch name
|
|
87
109
|
self.ctx.exit(2 if self.global_opts.strict else 0)
|
|
88
|
-
except FileNotFoundError as exc:
|
|
89
|
-
click.echo(str(exc), err=True)
|
|
90
|
-
self.ctx.exit(2)
|
|
91
110
|
except (
|
|
92
|
-
|
|
111
|
+
DetachedHeadGitError,
|
|
93
112
|
InvalidConfiguration,
|
|
94
113
|
InvalidGitRepositoryError,
|
|
114
|
+
ValidationError,
|
|
95
115
|
) as exc:
|
|
96
116
|
click.echo(str(exc), err=True)
|
|
97
117
|
self.ctx.exit(1)
|
|
@@ -4,6 +4,7 @@ import logging
|
|
|
4
4
|
import os
|
|
5
5
|
import subprocess
|
|
6
6
|
import sys
|
|
7
|
+
from collections import defaultdict
|
|
7
8
|
from datetime import datetime
|
|
8
9
|
from typing import TYPE_CHECKING
|
|
9
10
|
|
|
@@ -160,8 +161,17 @@ def shell(
|
|
|
160
161
|
if not shell:
|
|
161
162
|
raise TypeError("'shell' is None")
|
|
162
163
|
|
|
164
|
+
shell_cmd_param = defaultdict(
|
|
165
|
+
lambda: "-c",
|
|
166
|
+
{
|
|
167
|
+
"cmd": "/c",
|
|
168
|
+
"powershell": "-Command",
|
|
169
|
+
"pwsh": "-Command",
|
|
170
|
+
},
|
|
171
|
+
)
|
|
172
|
+
|
|
163
173
|
return subprocess.run( # noqa: S603
|
|
164
|
-
[shell,
|
|
174
|
+
[shell, shell_cmd_param[shell], cmd],
|
|
165
175
|
env=(env or {}),
|
|
166
176
|
check=check,
|
|
167
177
|
)
|
|
@@ -413,26 +423,28 @@ def version( # noqa: C901
|
|
|
413
423
|
* Create a release (if supported) in the remote VCS for this tag
|
|
414
424
|
"""
|
|
415
425
|
ctx = click.get_current_context()
|
|
416
|
-
|
|
417
|
-
|
|
426
|
+
|
|
427
|
+
# Enable any cli overrides of configuration before asking for the runtime context
|
|
428
|
+
config = cli_ctx.raw_config
|
|
418
429
|
|
|
419
430
|
# We can short circuit updating the release if we are only printing the last released version
|
|
420
431
|
if print_last_released or print_last_released_tag:
|
|
421
432
|
# TODO: get tag format a better way
|
|
422
|
-
if not (
|
|
433
|
+
if not (
|
|
434
|
+
last_release := last_released(config.repo_dir, tag_format=config.tag_format)
|
|
435
|
+
):
|
|
423
436
|
log.warning("No release tags found.")
|
|
424
437
|
return
|
|
425
438
|
|
|
426
439
|
click.echo(last_release[0] if print_last_released_tag else last_release[1])
|
|
427
440
|
return
|
|
428
441
|
|
|
442
|
+
# TODO: figure out --print of next version with & without branch validation
|
|
443
|
+
# do you always need a prerelease token if its not --as-prerelease?
|
|
444
|
+
runtime = cli_ctx.runtime_ctx
|
|
445
|
+
translator = runtime.version_translator
|
|
446
|
+
|
|
429
447
|
parser = runtime.commit_parser
|
|
430
|
-
forced_level_bump = None if not force_level else LevelBump.from_string(force_level)
|
|
431
|
-
prerelease = is_forced_prerelease(
|
|
432
|
-
as_prerelease=as_prerelease,
|
|
433
|
-
forced_level_bump=forced_level_bump,
|
|
434
|
-
prerelease=runtime.prerelease,
|
|
435
|
-
)
|
|
436
448
|
hvcs_client = runtime.hvcs_client
|
|
437
449
|
assets = runtime.assets
|
|
438
450
|
commit_author = runtime.commit_author
|
|
@@ -442,6 +454,13 @@ def version( # noqa: C901
|
|
|
442
454
|
opts = runtime.global_cli_options
|
|
443
455
|
gha_output = VersionGitHubActionsOutput(released=False)
|
|
444
456
|
|
|
457
|
+
forced_level_bump = None if not force_level else LevelBump.from_string(force_level)
|
|
458
|
+
prerelease = is_forced_prerelease(
|
|
459
|
+
as_prerelease=as_prerelease,
|
|
460
|
+
forced_level_bump=forced_level_bump,
|
|
461
|
+
prerelease=runtime.prerelease,
|
|
462
|
+
)
|
|
463
|
+
|
|
445
464
|
if prerelease_token:
|
|
446
465
|
log.info("Forcing use of %s as the prerelease token", prerelease_token)
|
|
447
466
|
translator.prerelease_token = prerelease_token
|
{python_semantic_release-9.8.4.dist-info → python_semantic_release-9.8.6.dist-info}/AUTHORS.rst
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_semantic_release-9.8.4.dist-info → python_semantic_release-9.8.6.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{python_semantic_release-9.8.4.dist-info → python_semantic_release-9.8.6.dist-info}/top_level.txt
RENAMED
|
File without changes
|