diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 4f4ccff82efc4fb7793a9cb8d516f01a5824a66b..21ef45c0a61d720f331f48b3ccf7bfb204723f18 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -88,6 +88,10 @@ blsmooth:
   script:
     - cwltool --no-container --preserve-environment LD_LIBRARY_PATH --preserve-environment PATH --preserve-environment PYTHONPATH steps/blsmooth.cwl test_jobs/blsmooth.json
 
+ddecal:
+  stage: test_steps
+  script:
+    - cwltool --no-container --preserve-environment LD_LIBRARY_PATH --preserve-environment PATH --preserve-environment PYTHONPATH steps/ddecal.cwl test_jobs/ddecal.json
 
 prefactor_calibrator:
   stage: integration_test
@@ -98,3 +102,4 @@ flag_average:
   stage: integration_test
   script:
     - cwltool --no-container --preserve-environment LD_LIBRARY_PATH --preserve-environment PATH test_workflow/flag_average.cwl --msin=/data/L570745_SB001_uv_first10.MS
+
diff --git a/steps/ddecal.cwl b/steps/ddecal.cwl
new file mode 100644
index 0000000000000000000000000000000000000000..f582c6b844c2243940a56a4b2e45e7b3186dff72
--- /dev/null
+++ b/steps/ddecal.cwl
@@ -0,0 +1,87 @@
+#!/usr/bin/env cwl-runner
+
+class: CommandLineTool
+cwlVersion: v1.0
+id: ddecal
+baseCommand: [DPPP]
+
+requirements:
+  InlineJavascriptRequirement: {}
+    
+hints:
+  DockerRequirement:
+    dockerPull: prefactor
+
+arguments:
+  - steps=[solve]
+  - solve.type=ddecal
+  - solve.h5parm=h5parm
+  - solve.mode=rotation+diagonal
+  - solve.uvlambdamin=300
+  - solve.maxiter=50
+  - solve.nchan=1
+  - solve.solint=1
+  - solve.propagateconvergedonly=True
+  - solve.flagdivergedonly=True
+  - solve.tolerance=1.e-3
+
+inputs:
+  - id: msin
+    type: Directory?
+    doc: Input Measurement Set
+    inputBinding:
+        prefix: msin=
+        separate: false
+
+  - id: msin_datacolumn
+    type: string
+    default: SMOOTHED_DATA
+    doc: Input data Column
+    inputBinding:
+        prefix: msin.datacolumn=
+        separate: false
+  - id: msout_name
+    type: string
+    doc: Output Measurement Set
+    default: out.MS
+    inputBinding:
+        prefix: msout=
+        separate: false
+  - id: usemodelcolumn
+    type: boolean
+    default: false
+    doc: |
+      Use model column. The model column name can be specified
+      with msin.modelcolumn (default MODEL_DATA)
+    inputBinding:
+        prefix: solve.usemodelcolumn=True
+
+#--------------------
+  - id: flagunconverged
+    type: boolean
+    default: false
+    doc: |
+      Flag unconverged solutions (i.e., those from solves that did not converge
+      within maxiter iterations).
+    inputBinding:
+      prefix: flagdivergedonly=True
+  - id: flagdivergedonly
+    default: false
+    type: boolean
+    doc: |
+      Flag only the unconverged solutions for which divergence was detected.
+      At the moment, this option is effective only for rotation+diagonal
+      solves, where divergence is detected when the amplitudes of any station
+      are found to be more than a factor of 5 from the mean amplitude over all
+      stations.
+      If divergence for any one station is detected, all stations are flagged
+      for that solution interval. Only effective when flagunconverged=true
+      and mode=rotation+diagonal.
+    inputBinding:
+      prefix: flagdivergedonly=True
+outputs:
+  - id: msout
+    doc: Output Measurement Set
+    type: Directory
+    outputBinding:
+      glob: $(inputs.msout_name=="."?inputs.msin:inputs.msout_name)
diff --git a/test_jobs/ddecal.json b/test_jobs/ddecal.json
new file mode 100644
index 0000000000000000000000000000000000000000..5103687772af9ca7461e3ed972a61fc60feea205
--- /dev/null
+++ b/test_jobs/ddecal.json
@@ -0,0 +1,8 @@
+{
+  "msin": {
+    "class": "Directory",
+    "path": "/data/L570745_SB001_uv_first10.MS"
+  },
+  "msin_datacolumn": "DATA", 
+  "usemodelcolumn": true
+}