File: test_version_release_notes.py

package info (click to toggle)
python-semantic-release 10.3.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 3,112 kB
  • sloc: python: 36,523; sh: 340; makefile: 156
file content (186 lines) | stat: -rw-r--r-- 5,997 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
from __future__ import annotations

import os
from datetime import timezone
from typing import TYPE_CHECKING

import pytest
from freezegun import freeze_time
from pytest_lazy_fixtures.lazy_fixture import lf as lazy_fixture

from semantic_release.version.version import Version

from tests.const import (
    EXAMPLE_RELEASE_NOTES_TEMPLATE,
    MAIN_PROG_NAME,
    VERSION_SUBCMD,
    RepoActionStep,
)
from tests.fixtures.repos import repo_w_no_tags_conventional_commits
from tests.fixtures.repos.trunk_based_dev.repo_w_no_tags import (
    repo_w_no_tags_emoji_commits,
    repo_w_no_tags_scipy_commits,
)
from tests.util import assert_successful_exit_code, get_release_history_from_context

if TYPE_CHECKING:
    from unittest.mock import MagicMock

    from requests_mock import Mocker

    from tests.conftest import GetStableDateNowFn, RunCliFn
    from tests.e2e.conftest import (
        RetrieveRuntimeContextFn,
    )
    from tests.fixtures.example_project import (
        UpdatePyprojectTomlFn,
        UseReleaseNotesTemplateFn,
    )
    from tests.fixtures.git_repo import (
        BuiltRepoResult,
        GenerateDefaultReleaseNotesFromDefFn,
        GetHvcsClientFromRepoDefFn,
    )


@pytest.mark.parametrize(
    "repo_result, next_release_version",
    [
        (lazy_fixture(repo_w_no_tags_conventional_commits.__name__), "1.0.0"),
    ],
)
def test_custom_release_notes_template(
    repo_result: BuiltRepoResult,
    next_release_version: str,
    run_cli: RunCliFn,
    use_release_notes_template: UseReleaseNotesTemplateFn,
    retrieve_runtime_context: RetrieveRuntimeContextFn,
    mocked_git_push: MagicMock,
    post_mocker: Mocker,
) -> None:
    """Verify the template `.release_notes.md.j2` from `template_dir` is used."""
    release_version = Version.parse(next_release_version)

    # Setup
    use_release_notes_template()
    runtime_context = retrieve_runtime_context(repo_result["repo"])

    # Act
    cli_cmd = [MAIN_PROG_NAME, VERSION_SUBCMD, "--vcs-release"]
    result = run_cli(cli_cmd[1:])

    # Must run this after the action because the release history object should be pulled from the
    # repository after a tag is created
    release_history = get_release_history_from_context(runtime_context)
    release = release_history.released[release_version]

    expected_release_notes = (
        runtime_context.template_environment.from_string(EXAMPLE_RELEASE_NOTES_TEMPLATE)
        .render(release=release)
        .rstrip()
        + os.linesep
    )

    # ensure normalized line endings after render
    expected_release_notes = str.join(
        os.linesep,
        str.split(expected_release_notes.replace("\r", ""), "\n"),
    )

    # Assert
    assert_successful_exit_code(result, cli_cmd)
    assert mocked_git_push.call_count == 2  # 1 for commit, 1 for tag
    assert post_mocker.call_count == 1
    assert post_mocker.last_request is not None

    actual_notes = post_mocker.last_request.json()["body"]
    assert expected_release_notes == actual_notes


@pytest.mark.parametrize(
    "repo_result, license_name, license_setting, mask_initial_release",
    [
        pytest.param(
            lazy_fixture(repo_fixture_name),
            license_name,
            license_setting,
            mask_initial_release,
            marks=pytest.mark.comprehensive,
        )
        for mask_initial_release in [True, False]
        for license_name in ["", "MIT", "GPL-3.0"]
        for license_setting in [
            "project.license-expression",
            "project.license",  # deprecated
            "project.license.text",  # deprecated
        ]
        for repo_fixture_name in [
            repo_w_no_tags_conventional_commits.__name__,
            repo_w_no_tags_emoji_commits.__name__,
            repo_w_no_tags_scipy_commits.__name__,
        ]
    ],
)
def test_default_release_notes_license_statement(
    repo_result: BuiltRepoResult,
    run_cli: RunCliFn,
    license_name: str,
    license_setting: str,
    mask_initial_release: bool,
    update_pyproject_toml: UpdatePyprojectTomlFn,
    mocked_git_push: MagicMock,
    post_mocker: Mocker,
    stable_now_date: GetStableDateNowFn,
    get_hvcs_client_from_repo_def: GetHvcsClientFromRepoDefFn,
    generate_default_release_notes_from_def: GenerateDefaultReleaseNotesFromDefFn,
):
    new_version = "1.0.0"

    # Setup
    now_datetime = stable_now_date()
    repo_def = list(repo_result["definition"])
    repo_def.append(
        {
            "action": RepoActionStep.RELEASE,
            "details": {
                "version": new_version,
                "datetime": now_datetime.isoformat(timespec="seconds"),
            },
        }
    )
    # Setup: Overwrite the default setting (defined in test.const)
    update_pyproject_toml("project.license-expression", None)

    # Setup: set the license for the test
    update_pyproject_toml(license_setting, license_name)

    # Setup: set mask_initial_release value in configuration
    update_pyproject_toml(
        "tool.semantic_release.changelog.default_templates.mask_initial_release",
        mask_initial_release,
    )

    expected_release_notes = generate_default_release_notes_from_def(
        version_actions=repo_def,
        hvcs=get_hvcs_client_from_repo_def(repo_def),
        previous_version=None,
        license_name=license_name,
        mask_initial_release=mask_initial_release,
    )

    # Act
    with freeze_time(now_datetime.astimezone(timezone.utc)):
        cli_cmd = [MAIN_PROG_NAME, VERSION_SUBCMD, "--no-changelog", "--vcs-release"]
        result = run_cli(cli_cmd[1:])

    # Evaluate
    assert_successful_exit_code(result, cli_cmd)
    assert mocked_git_push.call_count == 2  # 1 for commit, 1 for tag
    assert post_mocker.call_count == 1
    assert post_mocker.last_request is not None
    request_body = post_mocker.last_request.json()

    assert "body" in request_body
    actual_notes = request_body["body"]

    assert expected_release_notes == actual_notes