Skip to content

Commit a64cbc9

Browse files
authored
fix(config): ensure default config loads on network mounted windows environments (#1124)
Resolves: #1123 * test(cmd-generate-config): added noop version execution to validate config at runtime ref: #1123
1 parent 1346637 commit a64cbc9

File tree

2 files changed

+100
-11
lines changed

2 files changed

+100
-11
lines changed

src/semantic_release/cli/config.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -360,17 +360,21 @@ def verify_git_repo_dir(cls, dir_path: Path) -> Path:
360360
try:
361361
# Check for repository & walk up parent directories
362362
with Repo(str(dir_path), search_parent_directories=True) as git_repo:
363-
found_path = Path(
364-
git_repo.working_tree_dir or git_repo.working_dir
365-
).absolute()
363+
found_path = (
364+
Path(git_repo.working_tree_dir or git_repo.working_dir)
365+
.expanduser()
366+
.absolute()
367+
)
368+
366369
except InvalidGitRepositoryError as err:
367370
raise InvalidGitRepositoryError("No valid git repository found!") from err
368371

369372
if dir_path.absolute() != found_path:
370373
logging.warning(
371374
"Found .git/ in higher parent directory rather than provided in configuration."
372375
)
373-
return found_path
376+
377+
return found_path.resolve()
374378

375379
@field_validator("commit_parser", mode="after")
376380
@classmethod

tests/e2e/cmd_config/test_generate_config.py

Lines changed: 92 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,68 +9,153 @@
99
from semantic_release.cli.commands.main import main
1010
from semantic_release.cli.config import RawConfig
1111

12-
from tests.const import GENERATE_CONFIG_SUBCMD, MAIN_PROG_NAME
12+
from tests.const import GENERATE_CONFIG_SUBCMD, MAIN_PROG_NAME, VERSION_SUBCMD
13+
from tests.fixtures.repos import repo_w_no_tags_angular_commits
1314
from tests.util import assert_successful_exit_code
1415

1516
if TYPE_CHECKING:
17+
from pathlib import Path
1618
from typing import Any
1719

1820
from click.testing import CliRunner
1921

22+
from tests.fixtures.example_project import ExProjectDir
23+
2024

2125
@pytest.fixture
2226
def raw_config_dict() -> dict[str, Any]:
2327
return RawConfig().model_dump(mode="json", exclude_none=True)
2428

2529

2630
@pytest.mark.parametrize("args", [(), ("--format", "toml"), ("--format", "TOML")])
31+
@pytest.mark.usefixtures(repo_w_no_tags_angular_commits.__name__)
2732
def test_generate_config_toml(
28-
cli_runner: CliRunner, args: tuple[str], raw_config_dict: dict[str, Any]
33+
cli_runner: CliRunner,
34+
args: tuple[str],
35+
raw_config_dict: dict[str, Any],
36+
example_project_dir: ExProjectDir,
2937
):
38+
# Setup: Generate the expected configuration as a TOML string
3039
expected_config_as_str = tomlkit.dumps(
3140
{"semantic_release": raw_config_dict}
3241
).strip()
3342

43+
# Act: Print the generated configuration to stdout
3444
cli_cmd = [MAIN_PROG_NAME, GENERATE_CONFIG_SUBCMD, *args]
35-
3645
result = cli_runner.invoke(main, cli_cmd[1:])
3746

47+
# Evaluate: Check that the command ran successfully and that the output matches the expected configuration
3848
assert_successful_exit_code(result, cli_cmd)
3949
assert expected_config_as_str == result.output.strip()
4050

51+
# Setup: Write the generated configuration to a file
52+
config_file = "releaserc.toml"
53+
example_project_dir.joinpath(config_file).write_text(result.output)
54+
55+
# Act: Validate that the generated config is a valid configuration for PSR
56+
cli_cmd = [
57+
MAIN_PROG_NAME,
58+
"--noop",
59+
"--strict",
60+
"-c",
61+
config_file,
62+
VERSION_SUBCMD,
63+
"--print",
64+
]
65+
result = cli_runner.invoke(main, cli_cmd[1:])
66+
67+
# Evaluate: Check that the version command in noop mode ran successfully
68+
# which means PSR loaded the configuration successfully
69+
assert_successful_exit_code(result, cli_cmd)
70+
4171

4272
@pytest.mark.parametrize("args", [("--format", "json"), ("--format", "JSON")])
73+
@pytest.mark.usefixtures(repo_w_no_tags_angular_commits.__name__)
4374
def test_generate_config_json(
44-
cli_runner: CliRunner, args: tuple[str], raw_config_dict: dict[str, Any]
75+
cli_runner: CliRunner,
76+
args: tuple[str],
77+
raw_config_dict: dict[str, Any],
78+
example_project_dir: ExProjectDir,
4579
):
80+
# Setup: Generate the expected configuration as a JSON string
4681
expected_config_as_str = json.dumps(
4782
{"semantic_release": raw_config_dict}, indent=4
4883
).strip()
4984

85+
# Act: Print the generated configuration to stdout
5086
cli_cmd = [MAIN_PROG_NAME, GENERATE_CONFIG_SUBCMD, *args]
51-
5287
result = cli_runner.invoke(main, cli_cmd[1:])
5388

89+
# Evaluate: Check that the command ran successfully and that the output matches the expected configuration
5490
assert_successful_exit_code(result, cli_cmd)
5591
assert expected_config_as_str == result.output.strip()
5692

93+
# Setup: Write the generated configuration to a file
94+
config_file = "releaserc.json"
95+
example_project_dir.joinpath(config_file).write_text(result.output)
5796

97+
# Act: Validate that the generated config is a valid configuration for PSR
98+
cli_cmd = [
99+
MAIN_PROG_NAME,
100+
"--noop",
101+
"--strict",
102+
"-c",
103+
config_file,
104+
VERSION_SUBCMD,
105+
"--print",
106+
]
107+
result = cli_runner.invoke(main, cli_cmd[1:])
108+
109+
# Evaluate: Check that the version command in noop mode ran successfully
110+
# which means PSR loaded the configuration successfully
111+
assert_successful_exit_code(result, cli_cmd)
112+
113+
114+
@pytest.mark.usefixtures(repo_w_no_tags_angular_commits.__name__)
58115
def test_generate_config_pyproject_toml(
59-
cli_runner: CliRunner, raw_config_dict: dict[str, Any]
116+
cli_runner: CliRunner,
117+
raw_config_dict: dict[str, Any],
118+
example_pyproject_toml: Path,
60119
):
120+
# Setup: Generate the expected configuration as a TOML string according to PEP 518
61121
expected_config_as_str = tomlkit.dumps(
62122
{"tool": {"semantic_release": raw_config_dict}}
63123
).strip()
64124

125+
# Setup: Remove any current configuration from pyproject.toml
126+
pyproject_config = tomlkit.loads(example_pyproject_toml.read_text(encoding="utf-8"))
127+
pyproject_config.get("tool", {}).pop("semantic_release", None)
128+
example_pyproject_toml.write_text(tomlkit.dumps(pyproject_config))
129+
130+
# Act: Print the generated configuration to stdout
65131
cli_cmd = [
66132
MAIN_PROG_NAME,
67133
GENERATE_CONFIG_SUBCMD,
68134
"--format",
69135
"toml",
70136
"--pyproject",
71137
]
72-
73138
result = cli_runner.invoke(main, cli_cmd[1:])
74139

140+
# Evaluate: Check that the command ran successfully and that the output matches the expected configuration
75141
assert_successful_exit_code(result, cli_cmd)
76142
assert expected_config_as_str == result.output.strip()
143+
144+
# Setup: Write the generated configuration to a file
145+
example_pyproject_toml.write_text(
146+
str.join(
147+
"\n\n",
148+
[
149+
example_pyproject_toml.read_text(encoding="utf-8").strip(),
150+
result.output,
151+
],
152+
)
153+
)
154+
155+
# Act: Validate that the generated config is a valid configuration for PSR
156+
cli_cmd = [MAIN_PROG_NAME, "--noop", "--strict", VERSION_SUBCMD, "--print"]
157+
result = cli_runner.invoke(main, cli_cmd[1:])
158+
159+
# Evaluate: Check that the version command in noop mode ran successfully
160+
# which means PSR loaded the configuration successfully
161+
assert_successful_exit_code(result, cli_cmd)

0 commit comments

Comments
 (0)