Skip to content
Open
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
3 changes: 2 additions & 1 deletion src/semantic_release/changelog/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,8 @@ def read_file(filepath: str) -> str:
if not filepath:
raise FileNotFoundError("No file path provided") # noqa: TRY301

with Path(filepath).open(newline=os.linesep) as rfd:
# The changelog writer saves the changelog as UTF-8, so read it back the same way
with Path(filepath).open(newline=os.linesep, encoding="utf-8") as rfd:
return rfd.read()

except FileNotFoundError as err:
Expand Down
21 changes: 20 additions & 1 deletion tests/unit/semantic_release/changelog/test_changelog_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@
import pytest
from git import Commit, Object, Repo

from semantic_release.changelog.context import ChangelogMode, make_changelog_context
from semantic_release.changelog.context import (
ChangelogMode,
make_changelog_context,
read_file,
)
from semantic_release.changelog.release_history import Release, ReleaseHistory
from semantic_release.changelog.template import environment
from semantic_release.commit_parser import ParsedCommit
Expand Down Expand Up @@ -420,6 +424,21 @@ def test_changelog_context_read_file(
assert expected_changelog.encode() == actual_changelog.encode()


def test_read_file_reads_utf8_whatever_the_locale_encoding(tmp_path: Path):
"""
Given a UTF-8 changelog with non-ASCII text, when read_file reads it,
then the text is unchanged.
"""
changelog_file = tmp_path / "CHANGELOG.md"
# The cp1252 and cp949 code pages cannot decode the UTF-8 bytes of this text
content = (
"## v1.0.0 (2026-11-06)\n\n### ✨ Features\n\n- Add a greeting (by Łukasz)\n"
)
changelog_file.write_bytes(content.encode("utf-8"))

assert content == read_file(str(changelog_file))


@pytest.mark.parametrize("file_path", ["", "nonexistent.md"])
def test_changelog_context_read_file_fails_gracefully(
example_git_https_url: str,
Expand Down