Skip to content

Commit 7a1f822

Browse files
aconal-comaniketkarnecodejedi365
authored
fix(config): eliminate .git/ in parent dir warnings for monorepos configured with .. (#1444)
In monorepo setups where `repo_dir = '..'` is configured for a subpackage, `Path('..').absolute()` returns `/path/to/package/..` rather than the resolved `/path/to/repo`. This change resolves symlinks and normalizes paths, preventing additional `'Found .git/ in higher parent directory'` warnings. Resolves: #1418 * docs(configuration): document `repo_dir` config option * test(fixtures): update example monorepo to configure `repo_dir` as parent dir * test(cmd-version): update rebuild repo tests to check for `.git/` in parent dir warning * test(cmd-version): add e2e test to check for warning of `.git/` in parent dir * test(fixtures): adjust change directory for windows compatibility --------- Co-authored-by: Aniket Karne <aniketkarne@gmail.com> Co-authored-by: codejedi365 <codejedi365@users.noreply.github.com> Signed-off-by: codejedi365 <codejedi365@users.noreply.github.com>
1 parent 5fa2df5 commit 7a1f822

21 files changed

Lines changed: 204 additions & 27 deletions

docs/configuration/configuration.rst

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1208,6 +1208,25 @@ from the :ref:`remote.name <config-remote-name>` location of your git repository
12081208
12091209
----
12101210
1211+
.. _config-repo_dir:
1212+
1213+
``repo_dir``
1214+
""""""""""""
1215+
1216+
**Type:** ``str``
1217+
1218+
Specify the directory of the Git repository. This is used to determine the location of
1219+
the repository for various operations, such as creating tags and commits. PSR will attempt
1220+
to automatically determine the location of the repository in parent directories of the
1221+
current working directory but will emit a warning if it is higher than this defined value.
1222+
1223+
If a git repository is not found from this location or any parent directories, PSR will
1224+
raise an error and exit.
1225+
1226+
**Default:** ``"."``
1227+
1228+
----
1229+
12111230
.. _config-tag_format:
12121231
12131232
``tag_format``

src/semantic_release/cli/config.py

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,18 @@
1313
error as RegExpError, # noqa: N812
1414
escape as regex_escape,
1515
)
16-
from typing import Any, ClassVar, Dict, List, Literal, Optional, Tuple, Type, Union
16+
from typing import (
17+
Any,
18+
ClassVar,
19+
Dict,
20+
List,
21+
Literal,
22+
Optional,
23+
Tuple,
24+
Type,
25+
Union,
26+
cast,
27+
)
1728

1829
# typing_extensions is for Python 3.8, 3.9, 3.10 compatibility
1930
import tomlkit
@@ -363,7 +374,7 @@ class RawConfig(BaseModel):
363374
logging_use_named_masks: bool = False
364375
major_on_zero: bool = True
365376
allow_zero_version: bool = False
366-
repo_dir: Annotated[Path, Field(validate_default=True)] = Path(".")
377+
repo_dir: Path = Field(default=cast("Path", "."), validate_default=True)
367378
remote: RemoteConfig = RemoteConfig()
368379
no_git_verify: bool = False
369380
tag_format: str = "v{version}"
@@ -388,18 +399,19 @@ def verify_git_repo_dir(cls, dir_path: Path) -> Path:
388399
found_path = (
389400
Path(git_repo.working_tree_dir or git_repo.working_dir)
390401
.expanduser()
402+
.resolve()
391403
.absolute()
392404
)
393405

394406
except InvalidGitRepositoryError as err:
395-
raise InvalidGitRepositoryError("No valid git repository found!") from err
407+
msg = "No valid git repository found!"
408+
raise InvalidGitRepositoryError(msg) from err
396409

397-
if dir_path.absolute() != found_path:
398-
logging.warning(
399-
"Found .git/ in higher parent directory rather than provided in configuration."
400-
)
410+
if dir_path.resolve().absolute() != found_path:
411+
msg = "Found .git/ in higher parent directory rather than provided in configuration."
412+
logger.warning(msg)
401413

402-
return found_path.resolve()
414+
return found_path
403415

404416
@field_validator("commit_parser", mode="after")
405417
@classmethod

tests/e2e/cmd_version/bump_version/git_flow/test_repo_1_channel.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
repo_w_git_flow_emoji_commits,
1111
repo_w_git_flow_scipy_commits,
1212
)
13-
from tests.util import temporary_working_directory
13+
from tests.util import assert_str_not_in_output, temporary_working_directory
1414

1515
if TYPE_CHECKING:
1616
from pathlib import Path
@@ -66,6 +66,7 @@ def test_gitflow_repo_rebuild_1_channel(
6666
pyproject_toml_file: Path,
6767
changelog_md_file: Path,
6868
changelog_rst_file: Path,
69+
caplog: pytest.LogCaptureFixture,
6970
):
7071
# build target repo into a temporary directory
7172
target_repo_dir = example_project_dir / repo_fixture_name
@@ -153,6 +154,8 @@ def test_gitflow_repo_rebuild_1_channel(
153154

154155
# Evaluate (normal release actions should have occurred as expected)
155156
# ------------------------------------------------------------------
157+
# The warning should not be present in the logs since we are running in the same directory as the .git repo
158+
assert_str_not_in_output("Found .git/ in higher parent directory", caplog.text)
156159
# Make sure version file is updated
157160
assert expected_pyproject_toml_content == actual_pyproject_toml_content
158161
assert expected_version_file_content == actual_version_file_content

tests/e2e/cmd_version/bump_version/git_flow/test_repo_2_channels.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
repo_w_git_flow_w_alpha_prereleases_n_emoji_commits,
1111
repo_w_git_flow_w_alpha_prereleases_n_scipy_commits,
1212
)
13-
from tests.util import temporary_working_directory
13+
from tests.util import assert_str_not_in_output, temporary_working_directory
1414

1515
if TYPE_CHECKING:
1616
from pathlib import Path
@@ -66,6 +66,7 @@ def test_gitflow_repo_rebuild_2_channels(
6666
pyproject_toml_file: Path,
6767
changelog_md_file: Path,
6868
changelog_rst_file: Path,
69+
caplog: pytest.LogCaptureFixture,
6970
):
7071
# build target repo into a temporary directory
7172
target_repo_dir = example_project_dir / repo_fixture_name
@@ -153,6 +154,8 @@ def test_gitflow_repo_rebuild_2_channels(
153154

154155
# Evaluate (normal release actions should have occurred as expected)
155156
# ------------------------------------------------------------------
157+
# The warning should not be present in the logs since we are running in the same directory as the .git repo
158+
assert_str_not_in_output("Found .git/ in higher parent directory", caplog.text)
156159
# Make sure version file is updated
157160
assert expected_pyproject_toml_content == actual_pyproject_toml_content
158161
assert expected_version_file_content == actual_version_file_content

tests/e2e/cmd_version/bump_version/git_flow/test_repo_3_channels.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
repo_w_git_flow_w_rc_n_alpha_prereleases_n_emoji_commits,
1212
repo_w_git_flow_w_rc_n_alpha_prereleases_n_scipy_commits,
1313
)
14-
from tests.util import temporary_working_directory
14+
from tests.util import assert_str_not_in_output, temporary_working_directory
1515

1616
if TYPE_CHECKING:
1717
from pathlib import Path
@@ -68,6 +68,7 @@ def test_gitflow_repo_rebuild_3_channels(
6868
pyproject_toml_file: Path,
6969
changelog_md_file: Path,
7070
changelog_rst_file: Path,
71+
caplog: pytest.LogCaptureFixture,
7172
):
7273
# build target repo into a temporary directory
7374
target_repo_dir = example_project_dir / repo_fixture_name
@@ -154,6 +155,8 @@ def test_gitflow_repo_rebuild_3_channels(
154155

155156
# Evaluate (normal release actions should have occurred as expected)
156157
# ------------------------------------------------------------------
158+
# The warning should not be present in the logs since we are running in the same directory as the .git repo
159+
assert_str_not_in_output("Found .git/ in higher parent directory", caplog.text)
157160
# Make sure version file is updated
158161
assert expected_pyproject_toml_content == actual_pyproject_toml_content
159162
assert expected_version_file_content == actual_version_file_content

tests/e2e/cmd_version/bump_version/git_flow/test_repo_4_channels.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
repo_w_git_flow_w_beta_alpha_rev_prereleases_n_emoji_commits,
1111
repo_w_git_flow_w_beta_alpha_rev_prereleases_n_scipy_commits,
1212
)
13-
from tests.util import temporary_working_directory
13+
from tests.util import assert_str_not_in_output, temporary_working_directory
1414

1515
if TYPE_CHECKING:
1616
from pathlib import Path
@@ -66,6 +66,7 @@ def test_gitflow_repo_rebuild_4_channels(
6666
pyproject_toml_file: Path,
6767
changelog_md_file: Path,
6868
changelog_rst_file: Path,
69+
caplog: pytest.LogCaptureFixture,
6970
):
7071
# build target repo into a temporary directory
7172
target_repo_dir = example_project_dir / repo_fixture_name
@@ -153,6 +154,8 @@ def test_gitflow_repo_rebuild_4_channels(
153154

154155
# Evaluate (normal release actions should have occurred as expected)
155156
# ------------------------------------------------------------------
157+
# The warning should not be present in the logs since we are running in the same directory as the .git repo
158+
assert_str_not_in_output("Found .git/ in higher parent directory", caplog.text)
156159
# Make sure version file is updated
157160
assert expected_pyproject_toml_content == actual_pyproject_toml_content
158161
assert expected_version_file_content == actual_version_file_content

tests/e2e/cmd_version/bump_version/github_flow/test_repo_1_channel.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
repo_w_github_flow_w_default_release_channel_emoji_commits,
1111
repo_w_github_flow_w_default_release_channel_scipy_commits,
1212
)
13-
from tests.util import temporary_working_directory
13+
from tests.util import assert_str_not_in_output, temporary_working_directory
1414

1515
if TYPE_CHECKING:
1616
from pathlib import Path
@@ -66,6 +66,7 @@ def test_githubflow_repo_rebuild_1_channel(
6666
pyproject_toml_file: Path,
6767
changelog_md_file: Path,
6868
changelog_rst_file: Path,
69+
caplog: pytest.LogCaptureFixture,
6970
):
7071
# build target repo into a temporary directory
7172
target_repo_dir = example_project_dir / repo_fixture_name
@@ -153,6 +154,8 @@ def test_githubflow_repo_rebuild_1_channel(
153154

154155
# Evaluate (normal release actions should have occurred as expected)
155156
# ------------------------------------------------------------------
157+
# The warning should not be present in the logs since we are running in the same directory as the .git repo
158+
assert_str_not_in_output("Found .git/ in higher parent directory", caplog.text)
156159
# Make sure version file is updated
157160
assert expected_pyproject_toml_content == actual_pyproject_toml_content
158161
assert expected_version_file_content == actual_version_file_content

tests/e2e/cmd_version/bump_version/github_flow/test_repo_1_channel_branch_update_merge.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
repo_w_github_flow_w_default_release_n_branch_update_merge_emoji_commits,
1414
repo_w_github_flow_w_default_release_n_branch_update_merge_scipy_commits,
1515
)
16-
from tests.util import temporary_working_directory
16+
from tests.util import assert_str_not_in_output, temporary_working_directory
1717

1818
if TYPE_CHECKING:
1919
from pathlib import Path
@@ -72,6 +72,7 @@ def test_github_flow_repo_w_default_release_n_branch_update_merge(
7272
pyproject_toml_file: Path,
7373
changelog_md_file: Path,
7474
changelog_rst_file: Path,
75+
caplog: pytest.LogCaptureFixture,
7576
):
7677
# build target repo into a temporary directory
7778
target_repo_dir = example_project_dir / repo_fixture_name
@@ -166,6 +167,8 @@ def test_github_flow_repo_w_default_release_n_branch_update_merge(
166167

167168
# Evaluate (normal release actions should have occurred as expected)
168169
# ------------------------------------------------------------------
170+
# The warning should not be present in the logs since we are running in the same directory as the .git repo
171+
assert_str_not_in_output("Found .git/ in higher parent directory", caplog.text)
169172
# Make sure version file is updated
170173
assert expected_pyproject_toml_content == actual_pyproject_toml_content
171174
assert expected_version_file_content == actual_version_file_content

tests/e2e/cmd_version/bump_version/github_flow/test_repo_2_channels.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
repo_w_github_flow_w_feature_release_channel_emoji_commits,
1111
repo_w_github_flow_w_feature_release_channel_scipy_commits,
1212
)
13-
from tests.util import temporary_working_directory
13+
from tests.util import assert_str_not_in_output, temporary_working_directory
1414

1515
if TYPE_CHECKING:
1616
from pathlib import Path
@@ -66,6 +66,7 @@ def test_githubflow_repo_rebuild_2_channels(
6666
pyproject_toml_file: Path,
6767
changelog_md_file: Path,
6868
changelog_rst_file: Path,
69+
caplog: pytest.LogCaptureFixture,
6970
):
7071
# build target repo into a temporary directory
7172
target_repo_dir = example_project_dir / repo_fixture_name
@@ -153,6 +154,8 @@ def test_githubflow_repo_rebuild_2_channels(
153154

154155
# Evaluate (normal release actions should have occurred as expected)
155156
# ------------------------------------------------------------------
157+
# The warning should not be present in the logs since we are running in the same directory as the .git repo
158+
assert_str_not_in_output("Found .git/ in higher parent directory", caplog.text)
156159
# Make sure version file is updated
157160
assert expected_pyproject_toml_content == actual_pyproject_toml_content
158161
assert expected_version_file_content == actual_version_file_content

tests/e2e/cmd_version/bump_version/github_flow_monorepo/test_monorepo_1_channel.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from tests.fixtures.monorepos.github_flow import (
1313
monorepo_w_github_flow_w_default_release_channel_conventional_commits,
1414
)
15-
from tests.util import temporary_working_directory
15+
from tests.util import assert_str_not_in_output, temporary_working_directory
1616

1717
if TYPE_CHECKING:
1818
from typing import Literal, Sequence
@@ -71,6 +71,7 @@ def test_githubflow_monorepo_rebuild_1_channel(
7171
monorepo_pkg2_changelog_md_file: Path,
7272
monorepo_pkg1_changelog_rst_file: Path,
7373
monorepo_pkg2_changelog_rst_file: Path,
74+
caplog: pytest.LogCaptureFixture,
7475
):
7576
# build target repo into a temporary directory
7677
target_repo_dir = example_project_dir / repo_fixture_name
@@ -225,6 +226,10 @@ def test_githubflow_monorepo_rebuild_1_channel(
225226

226227
# Evaluate (normal release actions should have occurred as expected)
227228
# ------------------------------------------------------------------
229+
# The warning should not be present in the logs since we have configured repo_dir
230+
# to be the parent directory from where PSR is being run, so although it is in the
231+
# parent directory, it is known to the user and should not be a warning
232+
assert_str_not_in_output("Found .git/ in higher parent directory", caplog.text)
228233
# Make sure version file is updated
229234
assert (
230235
expected_pkg1_pyproject_toml_content == actual_pkg1_pyproject_toml_content

0 commit comments

Comments
 (0)