Repository: SFDO-Tooling/CumulusCI (python)

Issue:
Setting `skip_future_releases` option for `github_automerge_feature` task in cumulusci.yml to false is ignored.
### Describe the bug

Whenever I attempt to change the option `skip_future_releases` to `False` and run `github_automerge_main` it appears to be ignored. This is confirmed when I attempt to do the same in a flow like `release_beta` and run it.

### Reproduction steps

1. Create `feature/001`, `feature/002`, and `feature/003` branches.
2. Make a commit on your main branch.
3. Add the following to your `cumulusci.yml` file:
```
    github_automerge_main:
        options:
            skip_future_releases: False
```
5. Run `github_automerge_main`

Result: Not all branches are updated with commit on main.

Expected Result: All branches are updated by a commit on main.


### Your CumulusCI and Python versions

CumulusCI version: 3.75.1 (/Users/julianjoseph/.local/bin/cci)
Python version: 3.10.0 (/Users/julianjoseph/.local/pipx/venvs/cumulusci/bin/python)

### Operating System

MacOS 13.3.1 (a)

### Windows environment

_No response_

### CumulusCI installation method

pipx

### Error Gist

_No response_

### Additional information

This is very obvious when you run `github_automerge_main` task within a flow since you get CLI logs like this:

```
                    ------------------------------------------------------------                      
                    Running task: github_automerge_main                                               
                    ------------------------------------------------------------                      
                                                                                                      
                    Options:                                                                          
                      commit: e1d00d5cfa27d0fdabeb8a5e952fde8ca21732fe                                
                      source_branch: main                                                             
                      branch_prefix: feature.                                                         
                      skip_future_releases: True                                                      
                      update_future_releases: False  
```

A workaround is running `github_automerge_main` within the command task:

```
            4:
                task: command
                options:
                    command: cci task run github_automerge_main --skip_future_releases false
```

Pull request:
Fix skip_future_releases option
Fixes #3594

As written, skip_future_releases is always `True` for
`skip_future_releases: False` or `skip_future_releases: false` because
those get converted to booleans before being passed to
`process_bool_arg`. This was working as designed when run through the
CLI because the option doesn't go through the Pydantic model so it's a
`str`.


Patch:
diff --git a/cumulusci/tasks/github/merge.py b/cumulusci/tasks/github/merge.py
index 1134de004..9d9b7bfbd 100644
--- a/cumulusci/tasks/github/merge.py
+++ b/cumulusci/tasks/github/merge.py
@@ -49,9 +49,12 @@ class MergeBranch(BaseGithubTask):
             self.options[
                 "source_branch"
             ] = self.project_config.project__git__default_branch
-        self.options["skip_future_releases"] = process_bool_arg(
-            self.options.get("skip_future_releases") or True
-        )
+        if "skip_future_releases" not in self.options:
+            self.options["skip_future_releases"] = True
+        else:
+            self.options["skip_future_releases"] = process_bool_arg(
+                self.options.get("skip_future_releases")
+            )
         self.options["update_future_releases"] = process_bool_arg(
             self.options.get("update_future_releases") or False
         )


Test patch:
diff --git a/cumulusci/tasks/github/tests/test_merge.py b/cumulusci/tasks/github/tests/test_merge.py
index def544935..f84b62f29 100644
--- a/cumulusci/tasks/github/tests/test_merge.py
+++ b/cumulusci/tasks/github/tests/test_merge.py
@@ -641,7 +641,13 @@ class TestMergeBranch(MockUtilBase):
     def test_merge_to_future_release_branches(self):
         """Tests that commits to the main branch are merged to the expected feature branches"""
         self._setup_mocks(
-            ["main", "feature/230", "feature/232", "feature/300", "feature/work-item"]
+            [
+                "main",
+                "feature/230",
+                "feature/232",
+                "feature/300",
+                "feature/work-item",
+            ]
         )
 
         task = self._create_task(
@@ -660,6 +666,104 @@ class TestMergeBranch(MockUtilBase):
         assert ["feature/232", "feature/300"] == actual_branches
         assert 2 == len(responses.calls)
 
+    @responses.activate
+    def test_merge_to_future_release_branches_skip(self):
+        """Tests that commits to the main branch are merged to the expected feature branches"""
+        self._setup_mocks(
+            [
+                "main",
+                "feature/230",
+                "feature/232",
+                "feature/300",
+                "feature/302",
+                "feature/work-item",
+            ]
+        )
+
+        task = self._create_task(
+            task_config={
+                "options": {
+                    "source_branch": "feature/230",
+                    "branch_prefix": "feature/",
+                    "update_future_releases": False,
+                }
+            }
+        )
+        task._init_task()
+
+        actual_branches = [branch.name for branch in task._get_branches_to_merge()]
+
+        assert [] == actual_branches
+        assert 2 == len(responses.calls)
+
+    @responses.activate
+    def test_merge_to_future_release_branches_skip_future(self):
+        """
+        Tests that commits are not merged to "release" (numeric) branches
+        """
+
+        self._setup_mocks(
+            [
+                "main",
+                "feature/230",
+                "feature/232",
+                "feature/300",
+                "feature/work-item",
+            ]
+        )
+
+        task = self._create_task(
+            task_config={
+                "options": {
+                    "source_branch": "main",
+                    "branch_prefix": "feature/",
+                    "update_future_releases": False,
+                    "skip_future_releases": True,
+                }
+            }
+        )
+        task._init_task()
+
+        actual_branches = [branch.name for branch in task._get_branches_to_merge()]
+
+        assert ["feature/230", "feature/work-item"] == actual_branches
+        assert 2 == len(responses.calls)
+
+    @responses.activate
+    def test_merge_to_future_release_branches_noskip_future(self):
+        """Tests that commits to the main branch are merged to the expected feature branches"""
+        self._setup_mocks(
+            [
+                "main",
+                "feature/230",
+                "feature/232",
+                "feature/300",
+                "feature/work-item",
+            ]
+        )
+
+        task = self._create_task(
+            task_config={
+                "options": {
+                    "source_branch": "main",
+                    "branch_prefix": "feature/",
+                    "update_future_releases": False,
+                    "skip_future_releases": False,
+                }
+            }
+        )
+        task._init_task()
+
+        actual_branches = [branch.name for branch in task._get_branches_to_merge()]
+
+        assert [
+            "feature/230",
+            "feature/232",
+            "feature/300",
+            "feature/work-item",
+        ] == actual_branches
+        assert 2 == len(responses.calls)
+
     @responses.activate
     def test_merge_to_future_release_branches_missing_slash(self):
         """Tests that commits to the main branch are merged to the expected feature branches"""