Repository: reanahub/reana-client

Issue:
cli: cannot run workflow without inputs
Consider this simple serial workflow:
```yaml
workflow:
  type: serial
  specification:
    steps:
      - environment: 'docker.io/library/ubuntu:20.04'
        commands:
          - sleep 5
```

reana-client reports the YAML file as valid (with some warnings):
```console
$ reana-client validate
==> Verifying REANA specification file... .../reana.yaml
  -> SUCCESS: Valid REANA specification file.
==> Verifying REANA specification parameters... 
  -> WARNING: Workflow "inputs" are missing in the REANA specification.
==> Verifying workflow parameters and commands... 
  -> SUCCESS: Workflow parameters and commands appear valid.
==> Verifying dangerous workflow operations... 
  -> SUCCESS: Workflow operations appear valid.
```

But running the workflow fails:
```console
reana-client run 
==> Creating a workflow...
==> Verifying REANA specification file... .../reana.yaml
  -> SUCCESS: Valid REANA specification file.
==> Verifying REANA specification parameters... 
  -> WARNING: Workflow "inputs" are missing in the REANA specification.
==> Verifying workflow parameters and commands... 
  -> SUCCESS: Workflow parameters and commands appear valid.
==> Verifying dangerous workflow operations... 
  -> SUCCESS: Workflow operations appear valid.
==> Verifying compute backends in REANA specification file...
  -> SUCCESS: Workflow compute backends appear to be valid.
workflow.1
==> SUCCESS: File /reana.yaml was successfully uploaded.
==> Uploading files...
Traceback (most recent call last):
  [...]
  File "/home/madonado/data/reana/src/reana-client/reana_client/cli/files.py", line 400, in upload_files
    for filepath in filenames:
TypeError: 'NoneType' object is not iterable
```




Discussion:

Patch:
diff --git a/CHANGES.rst b/CHANGES.rst
index 749ebc2..d00ab33 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -6,6 +6,7 @@ Version 0.9.2 (UNRELEASED)
 
 - Fixes ``create_workflow_from_json`` API command to always send the workflow specification to the server.
 - Fixes ``list`` command to be case-insensitive when using the ``--sort`` flag to sort the workflow runs by a specific column name.
+- Fixes ``run`` wrapper command for workflows that do not contain ``inputs`` clause in their specification.
 
 Version 0.9.1 (2023-09-27)
 --------------------------
diff --git a/reana_client/cli/workflow.py b/reana_client/cli/workflow.py
index d23cb10..dbcf506 100644
--- a/reana_client/cli/workflow.py
+++ b/reana_client/cli/workflow.py
@@ -1160,7 +1160,6 @@ def workflow_run(
     ctx.invoke(
         upload_files,
         workflow=ctx.workflow_name,
-        filenames=None,
         access_token=access_token,
     )
     display_message("Starting workflow...", msg_type="info")


Test patch:
diff --git a/tests/conftest.py b/tests/conftest.py
index b6d483c..34bf4cd 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -1,7 +1,7 @@
 # -*- coding: utf-8 -*-
 #
 # This file is part of REANA.
-# Copyright (C) 2017, 2018, 2020, 2021, 2022 CERN.
+# Copyright (C) 2017, 2018, 2020, 2021, 2022, 2023 CERN.
 #
 # REANA is free software; you can redistribute it and/or modify it
 # under the terms of the MIT License; see LICENSE file for more details.
@@ -279,3 +279,16 @@ def cwl_workflow_spec_loaded():
         }
     }
     return cwl_workflow_spec
+
+
+@pytest.fixture()
+def spec_without_inputs():
+    """REANA specification without `inputs`."""
+    return {
+        "workflow": {
+            "type": "serial",
+            "steps": [
+                {"environment": "registry.example.org/foo/bar", "commands": ["sleep"]}
+            ],
+        }
+    }
diff --git a/tests/test_cli_workflows.py b/tests/test_cli_workflows.py
index 4f6bc82..5a0e7fe 100644
--- a/tests/test_cli_workflows.py
+++ b/tests/test_cli_workflows.py
@@ -1,7 +1,7 @@
 # -*- coding: utf-8 -*-
 #
 # This file is part of REANA.
-# Copyright (C) 2018, 2019, 2020, 2021, 2022 CERN.
+# Copyright (C) 2018, 2019, 2020, 2021, 2022, 2023 CERN.
 #
 # REANA is free software; you can redistribute it and/or modify it
 # under the terms of the MIT License; see LICENSE file for more details.
@@ -988,3 +988,30 @@ def test_yml_ext_specification(create_yaml_workflow_schema):
         result = runner.invoke(cli, ["validate", "-t", reana_token])
         assert result.exit_code != 0
         assert message in result.output
+
+
+def test_run_with_no_inputs(spec_without_inputs):
+    """Test running workflow when specification does not contain inputs."""
+    env = {"REANA_SERVER_URL": "localhost"}
+    reana_token = "000000"
+    runner = CliRunner(env=env)
+    with patch(
+        "reana_client.cli.workflow.workflow_create"
+    ) as cli_workflow_create, patch(
+        "reana_client.cli.workflow.workflow_start"
+    ) as cli_workflow_start, patch(
+        "reana_client.api.client.get_workflow_specification",
+        Mock(return_value={"specification": spec_without_inputs}),
+    ) as get_workflow_specification, patch(
+        "reana_client.api.client.upload_to_server"
+    ) as upload_to_server, runner.isolated_filesystem():
+        with open("reana.yaml", "w") as f:
+            yaml.dump(spec_without_inputs, f)
+
+        result = runner.invoke(cli, ["run", "-t", reana_token])
+
+        assert result.exit_code == 0
+        cli_workflow_create.assert_called()
+        cli_workflow_start.assert_called()
+        get_workflow_specification.assert_called()
+        upload_to_server.assert_not_called()