Skip to content

Commit c6948b5

Browse files
authored
Merge branch 'master' into feature/multi-package-support
2 parents 35b896f + 8a56903 commit c6948b5

File tree

7 files changed

+103
-7
lines changed

7 files changed

+103
-7
lines changed

CHANGES.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,19 @@ Version 1.3.0a [unreleased]
66

77
Work in progress.
88

9+
Version 1.2.2 [2026-01-28]
10+
--------------------------
11+
12+
Bugfixes
13+
~~~~~~~~
14+
15+
- Temporarily pinned drf-yasg to 1.21.11 `#565
16+
<https://github.com/openwisp/openwisp-utils/issues/565>`_
17+
- Fixed releaser to only commit tracked files `#552
18+
<https://github.com/openwisp/openwisp-utils/issues/552>`_
19+
- Releaser: Fixed insertion of backported bugfix entries in ReST changelog
20+
`#532 <https://github.com/openwisp/openwisp-utils/issues/532>`_
21+
922
Version 1.2.1 [2025-12-19]
1023
--------------------------
1124

openwisp_utils/releaser/changelog.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,17 @@ def run_git_cliff(version=None):
4545
file=sys.stderr,
4646
)
4747
sys.exit(1)
48-
48+
# Pull latest tags before calculating changelog
49+
try:
50+
subprocess.run(
51+
["git", "pull", "--tags"],
52+
capture_output=True,
53+
text=True,
54+
check=True,
55+
)
56+
except subprocess.CalledProcessError as e:
57+
print(f"Warning: Failed to pull tags: {e.stderr}", file=sys.stderr)
58+
# Run git-cliff to calculate changelog
4959
try:
5060
cmd = ["git", "cliff", "--unreleased", "--config", config_path]
5161
if version:

openwisp_utils/releaser/release.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -358,8 +358,8 @@ def main():
358358
["git", "checkout", "-b", release_branch], check=True, capture_output=True
359359
)
360360

361-
print("Adding all changed files to git...")
362-
subprocess.run(["git", "add", "."], check=True, capture_output=True)
361+
print("Adding tracked changes to git...")
362+
subprocess.run(["git", "add", "-u"], check=True, capture_output=True)
363363

364364
commit_message = f"{new_version} release"
365365
subprocess.run(

openwisp_utils/releaser/tests/conftest.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import os
12
import subprocess
23
from datetime import datetime
34
from pathlib import Path
@@ -157,7 +158,6 @@ def mock_all(mocker):
157158
stdout="main", check_returncode=True
158159
),
159160
}
160-
161161
default_mock = MagicMock(stdout="", stderr="", check_returncode=True)
162162

163163
def subprocess_side_effect(command, *args, **kwargs):
@@ -179,6 +179,15 @@ def subprocess_side_effect(command, *args, **kwargs):
179179
"openwisp_utils.releaser.version.questionary.select", new=mock_q_select
180180
)
181181

182+
# Mock OPENAI_CHATGPT_TOKEN to None to skip AI summary by default
183+
original_environ_get = os.environ.get
184+
185+
def mock_environ_get(key, default=None):
186+
if key == "OPENAI_CHATGPT_TOKEN":
187+
return None
188+
return original_environ_get(key, default)
189+
190+
mocker.patch("os.environ.get", side_effect=mock_environ_get)
182191
mocks = {
183192
"subprocess": mocker.patch(
184193
"openwisp_utils.releaser.release.subprocess.run",
@@ -236,5 +245,4 @@ def subprocess_side_effect(command, *args, **kwargs):
236245
}
237246
mocks["check_prerequisites"].return_value = (mock_config, mock_gh_instance)
238247
mocks["load_config"].return_value = mock_config
239-
240248
return mocks

openwisp_utils/releaser/tests/test_changelog.py

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,13 @@ def test_run_git_cliff_no_config(mock_find_config):
136136

137137

138138
@patch("openwisp_utils.releaser.changelog.find_cliff_config", return_value="path")
139-
@patch("subprocess.run", side_effect=FileNotFoundError)
139+
@patch("subprocess.run")
140140
def test_run_git_cliff_file_not_found(mock_run, mock_find_config):
141+
# First call (git pull --tags) succeeds, second call (git cliff) raises FileNotFoundError
142+
mock_run.side_effect = [
143+
subprocess.CompletedProcess(args=[], returncode=0, stdout="", stderr=""),
144+
FileNotFoundError,
145+
]
141146
with pytest.raises(SystemExit):
142147
run_git_cliff()
143148

@@ -322,6 +327,59 @@ def test_run_git_cliff_with_version_tag(mock_subprocess_run, mock_find_config):
322327
assert "--tag" in executed_cmd and "1.0.0" in executed_cmd
323328

324329

330+
@patch(
331+
"openwisp_utils.releaser.changelog.find_cliff_config",
332+
return_value="path/to/cliff.toml",
333+
)
334+
@patch("openwisp_utils.releaser.changelog.subprocess.run")
335+
def test_run_git_cliff_calls_git_pull_tags(mock_subprocess_run, mock_find_config):
336+
"""Tests that `git pull --tags` is executed before running git-cliff."""
337+
# Mock the subprocess.run to return different results for different calls
338+
mock_subprocess_run.return_value = subprocess.CompletedProcess(
339+
args=[], returncode=0, stdout="Changelog content", stderr=""
340+
)
341+
run_git_cliff()
342+
# Verify that subprocess.run was called twice: once for git pull --tags, once for git-cliff
343+
assert mock_subprocess_run.call_count == 2
344+
# Check the first call is for git pull --tags
345+
first_call_args = mock_subprocess_run.call_args_list[0][0][0]
346+
assert first_call_args == ["git", "pull", "--tags"]
347+
# Check the second call is for git cliff
348+
second_call_args = mock_subprocess_run.call_args_list[1][0][0]
349+
assert (
350+
"git" in second_call_args
351+
and "cliff" in second_call_args
352+
and "--unreleased" in second_call_args
353+
)
354+
355+
356+
@patch(
357+
"openwisp_utils.releaser.changelog.find_cliff_config",
358+
return_value="path/to/cliff.toml",
359+
)
360+
@patch("openwisp_utils.releaser.changelog.subprocess.run")
361+
@patch("builtins.print")
362+
def test_run_git_cliff_git_pull_tags_fails(
363+
mock_print, mock_subprocess_run, mock_find_config
364+
):
365+
"""Tests that `git pull --tags` failure is handled gracefully and git-cliff still runs."""
366+
# First call (git pull --tags) fails, second call (git cliff) succeeds
367+
mock_subprocess_run.side_effect = [
368+
subprocess.CalledProcessError(1, "git pull --tags", stderr="Network error"),
369+
subprocess.CompletedProcess(
370+
args=[], returncode=0, stdout="Changelog content", stderr=""
371+
),
372+
]
373+
run_git_cliff()
374+
# Verify that subprocess.run was called twice despite the first failure
375+
assert mock_subprocess_run.call_count == 2
376+
# Verify warning message was printed
377+
mock_print.assert_called_once()
378+
call_args = mock_print.call_args[0][0]
379+
assert "Warning: Failed to pull tags:" in call_args
380+
assert "Network error" in call_args
381+
382+
325383
def test_process_changelog_dependencies_as_last_section():
326384
"""Tests where 'Dependencies' is the last section."""
327385
changelog_text = (

openwisp_utils/tests/selenium.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,13 @@ def _setup_and_call(self, result, debug=False):
5353
stream=None, descriptions=None, verbosity=0
5454
)
5555
super()._setup_and_call(result, debug)
56+
# IMPORTANT: a skip is not a success; propagate it as a skip and stop.
57+
if getattr(result, "skipped", None):
58+
for _, reason in result.skipped:
59+
original_result.addSkip(self, reason)
60+
if hasattr(original_result, "events") and hasattr(result, "events"):
61+
original_result.events = result.events
62+
return
5663
if result.wasSuccessful():
5764
if attempt == 0:
5865
original_result.addSuccess(self)

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
"rest": [
4646
"djangorestframework~=3.16.0",
4747
"django-filter>=25.1,<26.0", # django-filter uses CalVer
48-
"drf-yasg~=1.21.7",
48+
"drf-yasg==1.21.11", # pinning due to https://github.com/openwisp/openwisp-utils/issues/565
4949
],
5050
"channels": [
5151
"channels[daphne]~=4.3.0",

0 commit comments

Comments
 (0)