python-semantic-release 9.8.4__py3-none-any.whl → 9.8.5__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.5.dist-info}/METADATA +1 -1
- {python_semantic_release-9.8.4.dist-info → python_semantic_release-9.8.5.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 +18 -9
- {python_semantic_release-9.8.4.dist-info → python_semantic_release-9.8.5.dist-info}/AUTHORS.rst +0 -0
- {python_semantic_release-9.8.4.dist-info → python_semantic_release-9.8.5.dist-info}/LICENSE +0 -0
- {python_semantic_release-9.8.4.dist-info → python_semantic_release-9.8.5.dist-info}/WHEEL +0 -0
- {python_semantic_release-9.8.4.dist-info → python_semantic_release-9.8.5.dist-info}/entry_points.txt +0 -0
- {python_semantic_release-9.8.4.dist-info → python_semantic_release-9.8.5.dist-info}/top_level.txt +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
semantic_release/__init__.py,sha256=
|
|
1
|
+
semantic_release/__init__.py,sha256=blL7pv_bzsszX08mfPgx5FgX1CIfqZ15ib-FGb8fxEA,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=sgyIGF62XR2hLAKuyXMdA8OI5OEaQky-kaSoWJYlBBQ,24110
|
|
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.5.dist-info/AUTHORS.rst,sha256=XOReVvpymEFUPsS2QPH97jlfJBVrxwS2eu8-jVAe4gk,230
|
|
51
|
+
python_semantic_release-9.8.5.dist-info/LICENSE,sha256=NE85nszX252sdQdu0xgS9qwfYES0k8qS6gW3uO4jRGE,1083
|
|
52
|
+
python_semantic_release-9.8.5.dist-info/METADATA,sha256=TjNY6oQvBuham-GTQSZyLa0uIXkrm4LZnPGwyqPF1SI,5404
|
|
53
|
+
python_semantic_release-9.8.5.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
54
|
+
python_semantic_release-9.8.5.dist-info/entry_points.txt,sha256=6bS6euSagjerp7onDtfI9_ZpczWreZF3gjHfGAegkbo,123
|
|
55
|
+
python_semantic_release-9.8.5.dist-info/top_level.txt,sha256=qYA24nyg3eP-ti5UW7Vuj2aXVmM0wqVHx4mREdRZNAA,17
|
|
56
|
+
python_semantic_release-9.8.5.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)
|
|
@@ -413,26 +413,28 @@ def version( # noqa: C901
|
|
|
413
413
|
* Create a release (if supported) in the remote VCS for this tag
|
|
414
414
|
"""
|
|
415
415
|
ctx = click.get_current_context()
|
|
416
|
-
|
|
417
|
-
|
|
416
|
+
|
|
417
|
+
# Enable any cli overrides of configuration before asking for the runtime context
|
|
418
|
+
config = cli_ctx.raw_config
|
|
418
419
|
|
|
419
420
|
# We can short circuit updating the release if we are only printing the last released version
|
|
420
421
|
if print_last_released or print_last_released_tag:
|
|
421
422
|
# TODO: get tag format a better way
|
|
422
|
-
if not (
|
|
423
|
+
if not (
|
|
424
|
+
last_release := last_released(config.repo_dir, tag_format=config.tag_format)
|
|
425
|
+
):
|
|
423
426
|
log.warning("No release tags found.")
|
|
424
427
|
return
|
|
425
428
|
|
|
426
429
|
click.echo(last_release[0] if print_last_released_tag else last_release[1])
|
|
427
430
|
return
|
|
428
431
|
|
|
432
|
+
# TODO: figure out --print of next version with & without branch validation
|
|
433
|
+
# do you always need a prerelease token if its not --as-prerelease?
|
|
434
|
+
runtime = cli_ctx.runtime_ctx
|
|
435
|
+
translator = runtime.version_translator
|
|
436
|
+
|
|
429
437
|
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
438
|
hvcs_client = runtime.hvcs_client
|
|
437
439
|
assets = runtime.assets
|
|
438
440
|
commit_author = runtime.commit_author
|
|
@@ -442,6 +444,13 @@ def version( # noqa: C901
|
|
|
442
444
|
opts = runtime.global_cli_options
|
|
443
445
|
gha_output = VersionGitHubActionsOutput(released=False)
|
|
444
446
|
|
|
447
|
+
forced_level_bump = None if not force_level else LevelBump.from_string(force_level)
|
|
448
|
+
prerelease = is_forced_prerelease(
|
|
449
|
+
as_prerelease=as_prerelease,
|
|
450
|
+
forced_level_bump=forced_level_bump,
|
|
451
|
+
prerelease=runtime.prerelease,
|
|
452
|
+
)
|
|
453
|
+
|
|
445
454
|
if prerelease_token:
|
|
446
455
|
log.info("Forcing use of %s as the prerelease token", prerelease_token)
|
|
447
456
|
translator.prerelease_token = prerelease_token
|
{python_semantic_release-9.8.4.dist-info → python_semantic_release-9.8.5.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.5.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{python_semantic_release-9.8.4.dist-info → python_semantic_release-9.8.5.dist-info}/top_level.txt
RENAMED
|
File without changes
|