Repository: cobbler/cobbler

Issue:
scm_track: Push script not working
### Describe the bug

After the refactoring of 

### Steps to reproduce

1. Enable `scm_track` 
2. Perform any change action in Cobbler
3. See error in logs

Note: The error with pathspec is already fixed on `main` through #3021.

### Expected behavior

Cobbler can push the commits to the specified remote.

### Cobbler version

<!--- Paste output from `cobbler version` -->
````paste below
cobbler:~ # cobbler version
Cobbler 3.3.3
  source: ?, ?
  build time: Thu Dec 19 12:00:00 2019
````

### Operating system

SLES 15 SP5

### Cobbler log

<!--- Paste (partial) output from `/var/log/cobbler/cobbler.log` -->
````paste below
[Thread-20] 2024-02-12T16:03:34 - DEBUG | running python triggers from /var/lib/cobbler/triggers/change/*
[Thread-20] 2024-02-12T16:03:34 - DEBUG | running python trigger cobbler.modules.scm_track
[Thread-20] 2024-02-12T16:03:34 - INFO | running: ['git', 'add', '--all', 'collections']
[Thread-20] 2024-02-12T16:03:34 - INFO | received on stdout: 
[Thread-20] 2024-02-12T16:03:34 - DEBUG | received on stderr: 
[Thread-20] 2024-02-12T16:03:34 - INFO | running: ['git', 'add', '--all', 'templates']
[Thread-20] 2024-02-12T16:03:34 - INFO | received on stdout: 
[Thread-20] 2024-02-12T16:03:34 - DEBUG | received on stderr: 
[Thread-20] 2024-02-12T16:03:34 - INFO | running: ['git', 'add', '--all', 'snippets']
[Thread-20] 2024-02-12T16:03:34 - INFO | received on stdout: 
[Thread-20] 2024-02-12T16:03:34 - DEBUG | received on stderr: 
[Thread-20] 2024-02-12T16:03:34 - INFO | running: ['git', 'commit', '-m', 'API', 'update', '--author', 'Cobbler <cobbler-scm-track@cobbler.arch.nue2.suse.org>']
[Thread-20] 2024-02-12T16:03:34 - INFO | received on stdout: 
[Thread-20] 2024-02-12T16:03:34 - DEBUG | received on stderr: error: pathspec 'update' did not match any file(s) known to git
````

### Screenshots

None

### Additional information

Snippet for from the settings:

```yaml
scm_track_enabled: true
scm_track_mode: "git"
scm_track_author: "Cobbler <cobbler-scm-track@cobbler.arch.nue2.suse.org>"
# scm_push_script: "git push"
scm_push_script: ""
```


Discussion:
This is broken since https://github.com/cobbler/cobbler/commit/470abbc4c925f68c6781373dcdd4fcf9be9679a8.

The issue is that the commit assumes that a single binary is called to push the code to somewhere.
Pathspec issue for Cobbler 3.3.4 is fixed via 3a09e163e86c7717db672c5e5470f8209761c941.

The remaining issue is fixing up the settings along with the push script.

Resolving patch:
diff --git a/cobbler/modules/scm_track.py b/cobbler/modules/scm_track.py
--- a/cobbler/modules/scm_track.py
+++ b/cobbler/modules/scm_track.py
@@ -64,7 +64,7 @@ def run(api: "CobblerAPI", args: Any):
         )
 
         if push_script:
-            utils.subprocess_call([push_script], shell=False)
+            utils.subprocess_call(push_script.split(" "), shell=False)
 
         os.chdir(old_dir)
         return 0
@@ -84,11 +84,11 @@ def run(api: "CobblerAPI", args: Any):
         utils.subprocess_call(["hg", "add templates"], shell=False)
         utils.subprocess_call(["hg", "add snippets"], shell=False)
         utils.subprocess_call(
-            ["hg", "commit", "-m", "API", "update", "--user", author], shell=False
+            ["hg", "commit", "-m", "API update", "--user", author], shell=False
         )
 
         if push_script:
-            utils.subprocess_call([push_script], shell=False)
+            utils.subprocess_call(push_script.split(" "), shell=False)
 
         os.chdir(old_dir)
         return 0


Test patch:
diff --git a/tests/modules/scm_track_test.py b/tests/modules/scm_track_test.py
--- a/tests/modules/scm_track_test.py
+++ b/tests/modules/scm_track_test.py
@@ -1,3 +1,8 @@
+"""
+TODO
+"""
+
+from typing import TYPE_CHECKING
 from unittest.mock import MagicMock
 
 import pytest
@@ -7,8 +12,14 @@
 from cobbler.modules import scm_track
 from cobbler.settings import Settings
 
+if TYPE_CHECKING:
+    from pytest_mock import MockerFixture
+
 
 def test_register():
+    """
+    Test if the trigger registers with the correct ID.
+    """
     # Arrange & Act
     result = scm_track.register()
 
@@ -17,6 +28,9 @@ def test_register():
 
 
 def test_run_unsupported():
+    """
+    Test that asserts that unsupported ``scm_track_mode`` options raise the correct exception.
+    """
     # Arrange
     settings_mock = MagicMock(name="scm_track_unsupported_setting_mock", spec=Settings)
     settings_mock.scm_track_enabled = True
@@ -29,10 +43,13 @@ def test_run_unsupported():
 
     # Act & Assert
     with pytest.raises(CX):
-        result = scm_track.run(api, args)
+        scm_track.run(api, args)
 
 
 def test_run_git():
+    """
+    Test that asserts that the Git integrations works as expected.
+    """
     # Arrange
     settings_mock = MagicMock(name="scm_track_git_setting_mock", spec=Settings)
     settings_mock.scm_track_enabled = True
@@ -51,7 +68,10 @@ def test_run_git():
     assert result == 0
 
 
-def test_run_hg(mocker):
+def test_run_hg(mocker: "MockerFixture"):
+    """
+    Test that asserts that the Mercurial integration works as expected.
+    """
     # Arrange
     settings_mock = MagicMock(name="scm_track_hg_setting_mock", spec=Settings)
     settings_mock.scm_track_enabled = True
@@ -67,25 +87,22 @@ def test_run_hg(mocker):
     result = scm_track.run(api, args)
 
     # Assert
-    subprocess_call.assert_has_calls(
-        [
-            mocker.call(["hg", "init"], shell=False),
-            mocker.call(["hg", "add collections"], shell=False),
-            mocker.call(["hg", "add templates"], shell=False),
-            mocker.call(["hg", "add snippets"], shell=False),
-            mocker.call(
-                [
-                    "hg",
-                    "commit",
-                    "-m",
-                    "API",
-                    "update",
-                    "--user",
-                    settings_mock.scm_track_author,
-                ],
-                shell=False,
-            ),
-            mocker.call(["/bin/true"], shell=False),
-        ]
-    )
+    assert subprocess_call.mock_calls == [
+        mocker.call(["hg", "init"], shell=False),
+        mocker.call(["hg", "add collections"], shell=False),
+        mocker.call(["hg", "add templates"], shell=False),
+        mocker.call(["hg", "add snippets"], shell=False),
+        mocker.call(
+            [
+                "hg",
+                "commit",
+                "-m",
+                "API update",
+                "--user",
+                settings_mock.scm_track_author,
+            ],
+            shell=False,
+        ),
+        mocker.call(["/bin/true"], shell=False),
+    ]
     assert result == 0