Repository: relekang/python-semantic-release
Pull request #436 (2022-04-10 21:56:56)

issue 354: if version_source=tag,then  don't read/write to a config file
> I would like to use semantic-release to publish new version tags in git, without updating any files/creating additional commits.
 
https://github.com/relekang/python-semantic-release/issues/354

Perhaps this was the original intention of this functionality - but I may be biased because this is the functionality I am after. Alternatively, this functionality could exist under a different config setting as per OP's issue: `tag_only` or something like that. 


Patch:
diff --git a/docs/configuration.rst b/docs/configuration.rst
index abbd875..7789053 100644
--- a/docs/configuration.rst
+++ b/docs/configuration.rst
@@ -92,6 +92,9 @@ The way we get and set the new version. Can be `commit` or `tag`.
   This won't change the source defined in :ref:`config-version_variable`.
 - If set to `commit`, will get the current version from the source defined in
   :ref:`config-version_variable`, edit the file and commit it.
+- If set to `tag_only`, then `version_variable` is ignored and no changes are made or committed to local
+  config files. The current version from the latest tag matching ``vX.Y.Z``.
+  This won't change the source defined in :ref:`config-version_variable`.
 
 Default: `commit`
 
diff --git a/semantic_release/cli.py b/semantic_release/cli.py
index 888cbb1..bed36b1 100644
--- a/semantic_release/cli.py
+++ b/semantic_release/cli.py
@@ -183,6 +183,14 @@ def bump_version(new_version, level_bump):
 
     Edit in the source code, commit and create a git tag.
     """
+    logger.info(f"Bumping with a {level_bump} version to {new_version}")
+    if config.get("version_source") == "tag_only":
+        tag_new_version(new_version)
+
+        # we are done, no need for file changes if we are using
+        # tags as version source
+        return
+
     set_new_version(new_version)
     if config.get(
         "commit_version_number",
@@ -192,8 +200,6 @@ def bump_version(new_version, level_bump):
     if config.get("version_source") == "tag" or config.get("tag_commit"):
         tag_new_version(new_version)
 
-    logger.info(f"Bumping with a {level_bump} version to {new_version}")
-
 
 def changelog(*, unreleased=False, noop=False, post=False, prerelease=False, **kwargs):
     """


Test patch:
diff --git a/tests/test_cli.py b/tests/test_cli.py
index c17212f..1cd2e07 100644
--- a/tests/test_cli.py
+++ b/tests/test_cli.py
@@ -94,6 +94,41 @@ def test_version_by_tag_with_commit_version_number_should_call_correct_functions
     mock_tag_new_version.assert_called_once_with("2.0.0")
 
 
+def test_version_by_tag_only_with_commit_version_number_should_call_correct_functions(
+    mocker,
+):
+
+    mocker.patch(
+        "semantic_release.cli.config.get",
+        wrapped_config_get(
+            version_source="tag_only",
+            commit_version_number=True,
+        ),
+    )
+
+    mock_set_new_version = mocker.patch("semantic_release.cli.set_new_version")
+    mock_tag_new_version = mocker.patch("semantic_release.cli.tag_new_version")
+    mock_commit_new_version = mocker.patch("semantic_release.cli.commit_new_version")
+    mock_new_version = mocker.patch(
+        "semantic_release.cli.get_new_version", return_value="2.0.0"
+    )
+    mock_evaluate_bump = mocker.patch(
+        "semantic_release.cli.evaluate_version_bump", return_value="major"
+    )
+    mock_current_version = mocker.patch(
+        "semantic_release.cli.get_current_version", return_value="1.2.3"
+    )
+
+    version()
+
+    mock_current_version.assert_called_once_with(False)
+    mock_evaluate_bump.assert_called_once_with("1.2.3", None)
+    mock_new_version.assert_called_once_with("1.2.3", "major", False)
+    assert not mock_set_new_version.called
+    assert not mock_commit_new_version.called
+    mock_tag_new_version.assert_called_once_with("2.0.0")
+
+
 def test_version_by_tag_should_call_correct_functions(mocker):
     mocker.patch(
         "semantic_release.cli.config.get",
@@ -120,6 +155,32 @@ def test_version_by_tag_should_call_correct_functions(mocker):
     mock_tag_new_version.assert_called_once_with("2.0.0")
 
 
+def test_version_by_tag_only_should_call_correct_functions(mocker):
+    mocker.patch(
+        "semantic_release.cli.config.get",
+        wrapped_config_get(version_source="tag_only"),
+    )
+    mock_set_new_version = mocker.patch("semantic_release.cli.set_new_version")
+    mock_tag_new_version = mocker.patch("semantic_release.cli.tag_new_version")
+    mock_new_version = mocker.patch(
+        "semantic_release.cli.get_new_version", return_value="2.0.0"
+    )
+    mock_evaluate_bump = mocker.patch(
+        "semantic_release.cli.evaluate_version_bump", return_value="major"
+    )
+    mock_current_version = mocker.patch(
+        "semantic_release.cli.get_current_version", return_value="1.2.3"
+    )
+
+    version()
+
+    mock_current_version.assert_called_once_with(False)
+    mock_evaluate_bump.assert_called_once_with("1.2.3", None)
+    mock_new_version.assert_called_once_with("1.2.3", "major", False)
+    assert not mock_set_new_version.called
+    mock_tag_new_version.assert_called_once_with("2.0.0")
+
+
 def test_version_by_commit_without_tag_should_call_correct_functions(mocker):
     mocker.patch(
         "semantic_release.cli.config.get",
@@ -487,6 +548,29 @@ def test_version_by_tag_check_build_status_succeeds(mocker):
     assert mock_tag_new_version.called
 
 
+def test_version_by_tag_only_check_build_status_succeeds(mocker):
+    mocker.patch(
+        "semantic_release.cli.config.get",
+        wrapped_config_get(
+            version_source="tag_only",
+            commit_version_number=False,
+            check_build_status=True,
+        ),
+    )
+    mock_check_build_status = mocker.patch(
+        "semantic_release.cli.check_build_status", return_value=True
+    )
+    mock_set_new_version = mocker.patch("semantic_release.cli.set_new_version")
+    mock_tag_new_version = mocker.patch("semantic_release.cli.tag_new_version")
+    mocker.patch("semantic_release.cli.evaluate_version_bump", lambda *x: "major")
+
+    version()
+
+    assert mock_check_build_status.called
+    assert not mock_set_new_version.called
+    assert mock_tag_new_version.called
+
+
 def test_version_check_build_status_not_called_if_disabled(mocker):
     mock_check_build_status = mocker.patch("semantic_release.cli.check_build_status")
     mocker.patch("semantic_release.cli.config.get", lambda *x, **y: False)