Repository: ansible-collections/community.general

Issue:
deploy_helper: missing release parameter for state=clean causes an error
**Summary**

The description of `release` parameter says that it is optional for `state=present` and required for `state=finalize`, but says nothing about `state=clean`. Executing a task with `state=clean` but without the `release` parameter causes an error

**Issue Type**

Bug Report

**Component Name**

deploy_helper

**Ansible Version**

```
ansible 2.10.5
  config file = /Users/maxim/Projects/XXX/ansible.cfg
  configured module search path = ['/Users/maxim/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /Users/maxim/Library/Python/3.7/lib/python/site-packages/ansible
  executable location = /Users/maxim/Library/Python/3.7/bin/ansible
  python version = 3.7.3 (default, Apr 24 2020, 18:51:23) [Clang 11.0.3 (clang-1103.0.32.62)]
```


**Configuration**

_No response_

**OS / Environment**

MacOS Catalina (10.15) on control node, and Ubuntu 20.04 on managed node

**Steps To Reproduce**

```yaml
- community.general.deploy_helper:
    path: '{{ deploy_helper.project_path }}'
    state: clean
```


**Expected Results**

I don't know exactly how this should work, but I think we should add that the `release` parameter is required for `state=clean`, and handle this in code. Also the examples of use look wrong

**Actual Results**

```
The full traceback is:
Traceback (most recent call last):
  File "/home/XXX/.ansible/tmp/ansible-tmp-1613593157.5376189-33857-233175515274164/AnsiballZ_deploy_helper.py", line 102, in <module>
    _ansiballz_main()
  File "/home/XXX/.ansible/tmp/ansible-tmp-1613593157.5376189-33857-233175515274164/AnsiballZ_deploy_helper.py", line 94, in _ansiballz_main
    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
  File "/home/XXX/.ansible/tmp/ansible-tmp-1613593157.5376189-33857-233175515274164/AnsiballZ_deploy_helper.py", line 40, in invoke_module
    runpy.run_module(mod_name='ansible_collections.community.general.plugins.modules.deploy_helper', init_globals=None, run_name='__main__', alter_sys=True)
  File "/usr/lib/python3.8/runpy.py", line 207, in run_module
    return _run_module_code(code, init_globals, run_name, mod_spec)
  File "/usr/lib/python3.8/runpy.py", line 97, in _run_module_code
    _run_code(code, mod_globals, init_globals,
  File "/usr/lib/python3.8/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/tmp/ansible_community.general.deploy_helper_payload_zq3sjtgk/ansible_community.general.deploy_helper_payload.zip/ansible_collections/community/general/plugins/modules/deploy_helper.py", line 524, in <module>
  File "/tmp/ansible_community.general.deploy_helper_payload_zq3sjtgk/ansible_community.general.deploy_helper_payload.zip/ansible_collections/community/general/plugins/modules/deploy_helper.py", line 506, in main
  File "/tmp/ansible_community.general.deploy_helper_payload_zq3sjtgk/ansible_community.general.deploy_helper_payload.zip/ansible_collections/community/general/plugins/modules/deploy_helper.py", line 411, in remove_unfinished_link
TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'
fatal: [XXX]: FAILED! => {
    "changed": false,
    "module_stderr": "Shared connection to XXX closed.\r\n",
    "module_stdout": "Traceback (most recent call last):\r\n  File \"/home/XXX/.ansible/tmp/ansible-tmp-1613593157.5376189-33857-233175515274164/AnsiballZ_deploy_helper.py\", line 102, in <module>\r\n    _ansiballz_main()\r\n  File \"/home/XXX/.ansible/tmp/ansible-tmp-1613593157.5376189-33857-233175515274164/AnsiballZ_deploy_helper.py\", line 94, in _ansiballz_main\r\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\r\n  File \"/home/XXX/.ansible/tmp/ansible-tmp-1613593157.5376189-33857-233175515274164/AnsiballZ_deploy_helper.py\", line 40, in invoke_module\r\n    runpy.run_module(mod_name='ansible_collections.community.general.plugins.modules.deploy_helper', init_globals=None, run_name='__main__', alter_sys=True)\r\n  File \"/usr/lib/python3.8/runpy.py\", line 207, in run_module\r\n    return _run_module_code(code, init_globals, run_name, mod_spec)\r\n  File \"/usr/lib/python3.8/runpy.py\", line 97, in _run_module_code\r\n    _run_code(code, mod_globals, init_globals,\r\n  File \"/usr/lib/python3.8/runpy.py\", line 87, in _run_code\r\n    exec(code, run_globals)\r\n  File \"/tmp/ansible_community.general.deploy_helper_payload_zq3sjtgk/ansible_community.general.deploy_helper_payload.zip/ansible_collections/community/general/plugins/modules/deploy_helper.py\", line 524, in <module>\r\n  File \"/tmp/ansible_community.general.deploy_helper_payload_zq3sjtgk/ansible_community.general.deploy_helper_payload.zip/ansible_collections/community/general/plugins/modules/deploy_helper.py\", line 506, in main\r\n  File \"/tmp/ansible_community.general.deploy_helper_payload_zq3sjtgk/ansible_community.general.deploy_helper_payload.zip/ansible_collections/community/general/plugins/modules/deploy_helper.py\", line 411, in remove_unfinished_link\r\nTypeError: unsupported operand type(s) for +: 'NoneType' and 'str'\r\n",
    "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error",
    "rc": 1
}
```




Discussion:
Files identified in the description:
* [`plugins/modules/web_infrastructure/deploy_helper.py`](https://github.com/ansible-collections/community.general/blob/master/plugins/modules/web_infrastructure/deploy_helper.py)

If these files are inaccurate, please update the `component name` section of the description or use the `!component` bot command.

[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: components_banner --->
cc @nerzhul @ramondelafuente
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->

Resolving patch:
diff --git a/plugins/modules/web_infrastructure/deploy_helper.py b/plugins/modules/web_infrastructure/deploy_helper.py
--- a/plugins/modules/web_infrastructure/deploy_helper.py
+++ b/plugins/modules/web_infrastructure/deploy_helper.py
@@ -408,6 +408,9 @@ def remove_unfinished_builds(self, releases_path):
     def remove_unfinished_link(self, path):
         changed = False
 
+        if not self.release:
+            return changed
+
         tmp_link_name = os.path.join(path, self.release + '.' + self.unfinished_filename)
         if not self.module.check_mode and os.path.exists(tmp_link_name):
             changed = True


Test patch: