Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/semantic_release/cli/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,12 @@ def from_raw_config( # noqa: C901
# Retrieve details from repository
with Repo(str(raw.repo_dir)) as git_repo:
try:
remote_url = raw.remote.url or git_repo.remote(raw.remote.name).url
# Get the remote url by calling out to `git remote get-url`. This returns
# the expanded url, taking into account any insteadOf directives
# in the git configuration.
remote_url = raw.remote.url or git_repo.git.remote(
"get-url", raw.remote.name
)
active_branch = git_repo.active_branch.name
except ValueError as err:
raise MissingGitRemote(
Expand Down
2 changes: 1 addition & 1 deletion src/semantic_release/hvcs/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class HvcsBase(metaclass=ABCMeta):
"""

def __init__(self, remote_url: str, *args: Any, **kwargs: Any) -> None:
self._remote_url = remote_url
self._remote_url = remote_url if parse_git_url(remote_url) else ""
self._name: str | None = None
self._owner: str | None = None

Expand Down
54 changes: 52 additions & 2 deletions tests/unit/semantic_release/cli/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
import os
import shutil
import sys
from pathlib import Path
from pathlib import Path, PurePosixPath
from re import compile as regexp
from typing import TYPE_CHECKING
from unittest import mock

import pytest
import tomlkit
from pydantic import RootModel, ValidationError
from urllib3.util.url import parse_url

import semantic_release
from semantic_release.cli.config import (
Expand All @@ -21,6 +22,7 @@
HvcsClient,
RawConfig,
RuntimeContext,
_known_hvcs,
)
from semantic_release.cli.util import load_raw_config_file
from semantic_release.commit_parser.angular import AngularParserOptions
Expand All @@ -43,7 +45,7 @@
from typing import Any

from tests.fixtures.example_project import ExProjectDir, UpdatePyprojectTomlFn
from tests.fixtures.git_repo import BuildRepoFn, CommitConvention
from tests.fixtures.git_repo import BuildRepoFn, BuiltRepoResult, CommitConvention


@pytest.mark.parametrize(
Expand Down Expand Up @@ -413,3 +415,51 @@ def test_changelog_config_default_insertion_flag(
)

assert changelog_config.insertion_flag == insertion_flag


@pytest.mark.parametrize(
"hvcs_type",
[k.value for k in _known_hvcs],
)
def test_git_remote_url_w_insteadof_alias(
repo_w_initial_commit: BuiltRepoResult,
example_pyproject_toml: Path,
example_git_https_url: str,
hvcs_type: str,
update_pyproject_toml: UpdatePyprojectTomlFn,
):
expected_url = parse_url(example_git_https_url)
repo_name_suffix = PurePosixPath(expected_url.path or "").name
insteadof_alias = "psr_test_insteadof"
insteadof_value = expected_url.url.replace(repo_name_suffix, "")
repo = repo_w_initial_commit["repo"]

with repo.config_writer() as cfg:
# Setup: define the insteadOf replacement value
cfg.add_value(f'url "{insteadof_value}"', "insteadof", f"{insteadof_alias}:")

# Setup: set the remote URL with an insteadOf alias
cfg.set_value('remote "origin"', "url", f"{insteadof_alias}:{repo_name_suffix}")

# Setup: set each supported HVCS client type
update_pyproject_toml("tool.semantic_release.remote.type", hvcs_type)

# Act: load the configuration (in clear environment)
with mock.patch.dict(os.environ, {}, clear=True):
# Essentially the same as CliContextObj._init_runtime_ctx()
project_config = tomlkit.loads(
example_pyproject_toml.read_text(encoding="utf-8")
).unwrap()

runtime = RuntimeContext.from_raw_config(
raw=RawConfig.model_validate(
project_config.get("tool", {}).get("semantic_release", {}),
),
global_cli_options=GlobalCommandLineOptions(),
)

# Trigger a function that calls helpers.parse_git_url()
actual_url = runtime.hvcs_client.remote_url(use_token=False)

# Evaluate: the remote URL should be the full URL
assert expected_url.url == actual_url
7 changes: 2 additions & 5 deletions tests/unit/semantic_release/hvcs/test__base.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,6 @@ def test_get_repository_name(remote_url, owner):
"git@gitlab.com/somewhere",
],
)
def test_hvcs_parse_error(bad_url):
client = ArbitraryHvcs(bad_url)
def test_hvcs_parse_error(bad_url: str):
with pytest.raises(ValueError):
_ = client.repo_name
with pytest.raises(ValueError):
_ = client.owner
ArbitraryHvcs(bad_url)