<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://vsmalladi.github.io/openwdl.github.io//feed.xml" rel="self" type="application/atom+xml" /><link href="https://vsmalladi.github.io/openwdl.github.io//" rel="alternate" type="text/html" /><updated>2026-02-25T20:02:28+00:00</updated><id>https://vsmalladi.github.io/openwdl.github.io//feed.xml</id><title type="html">OpenWDL</title><subtitle>Community driven open-development workflow language.</subtitle><author><name>OpenWDL</name></author><entry><title type="html">Announcing WDL 1.1.3</title><link href="https://vsmalladi.github.io/openwdl.github.io//wdl/bioinformatics/workflows/announcing-wdl-1-1-3/" rel="alternate" type="text/html" title="Announcing WDL 1.1.3" /><published>2026-02-15T18:00:00+00:00</published><updated>2026-02-15T18:00:00+00:00</updated><id>https://vsmalladi.github.io/openwdl.github.io//wdl/bioinformatics/workflows/announcing-wdl-1-1-3</id><content type="html" xml:base="https://vsmalladi.github.io/openwdl.github.io//wdl/bioinformatics/workflows/announcing-wdl-1-1-3/"><![CDATA[<h1 id="announcing-wdl-113">Announcing WDL 1.1.3</h1>

<p>The <a href="https://openwdl.org/">OpenWDL</a> community is pleased to announce the
release of <a href="https://github.com/openwdl/wdl/blob/wdl-1.1/SPEC.md">Workflow Description Language (WDL)
1.1.3</a>! The full list of issues and PR’s can be found in <a href="https://github.com/openwdl/wdl/milestone/5?closed=1">1.1.3 milestone</a></p>

<h2 id="whats-new">What’s new?</h2>

<p>This patch release addresses many issues with the clarity of the specification that have been raised by the community and also adds some improvements to its testing infrastructure and some bug fixes. Note that this release does not introduce any new features or change any existing functionality.</p>

<h3 id="testing-infrastructure-and-improvements">Testing Infrastructure and Improvements</h3>

<p>The biggest improvement introduced in this release is that we have switched our compliance suite to use <a href="https://github.com/openwdl/spectool">spectool</a>. This new tools allows you to parse the examples in a <a href="https://github.com/openwdl/spectool/blob/main/docs/SPEC.md">standardized format</a> and test cases in the spec into discrete testable WDL files that can be verified by your engine of choice.</p>

<h4 id="engine-compatibility">Engine compatibility</h4>

<p>We have improved our testing infrastructure so that when anyone in the community wants to make a change we have automatic <a href="https://github.com/openwdl/wdl/tree/wdl-1.1/.github/workflows">Github Actions</a> that run for the current major engines:</p>

<ul>
  <li><a href="https://cromwell.readthedocs.io/en/latest/">Cromwell</a></li>
  <li><a href="https://miniwdl.readthedocs.io/en/latest/">miniwdl</a></li>
  <li><a href="https://toil.ucsc-cgl.org/">Toil</a></li>
  <li><a href="https://sprocket.bio/">Sprocket</a></li>
</ul>

<p>We have created <a href="https://github.com/openwdl/wdl/blob/wdl-1.1/README.md#workflow-description-language-wdl">badges</a> that highlight how many of the tests pass for each engine. Full compliance will be at 100% pass rate.</p>

<h4 id="test-case-bug-fixes-and-corrections">Test Case Bug Fixes and Corrections</h4>

<p>Additionally, as we implemented our new Continuous Integration (CI) testing pipeline, we discovered many test cases needed to be fixed or clarified in order to just be executed. Many of these fixes were implemented thanks to <a href="https://github.com/stxue1">@stxue1</a> and <a href="https://github.com/vsmalladi">@vsmalladi</a>, with contributions from <a href="https://github.com/jdidion">@jdidion</a> and reviews from <a href="https://github.com/adamnovak">@adamnovak</a> and <a href="https://github.com/claymcleod">@claymcleod</a>. Below is a summary of some of the big fixes and clarifications.</p>

<h5 id="fixes">Fixes</h5>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>* GPU test example fails due to missing `lspci` command in default containers - fixed by specifying a container with `pciutils` ([#659](https://github.com/openwdl/wdl/pull/659)).
* WDL comment test incorrectly uses `cat` on numeric values - fixed by using `echo` instead ([#660](https://github.com/openwdl/wdl/pull/660)).
* Unit test expected outputs mismatch actual workflow outputs (e.g., struct keys, task output names) ([#661](https://github.com/openwdl/wdl/issues/661), [#663](https://github.com/openwdl/wdl/issues/663)) - part of [#669](https://github.com/openwdl/wdl/pull/669).
* Missing output sections in unit tests causing no outputs in runners ([#662](https://github.com/openwdl/wdl/issues/662)) - part of [#669](https://github.com/openwdl/wdl/pull/669).
* Call statements missing required inputs or `input:` keyword, violating WDL syntax ([#664](https://github.com/openwdl/wdl/issues/664), [#665](https://github.com/openwdl/wdl/issues/665)) - part of [#669](https://github.com/openwdl/wdl/pull/669).
* Python heredoc examples with indentation errors causing `IndentationError` ([#668](https://github.com/openwdl/wdl/issues/668)) - part of [#669](https://github.com/openwdl/wdl/pull/669).
* `read_json()` fails on Python-stringified output due to single quotes - fixed by ensuring valid JSON format ([#671](https://github.com/openwdl/wdl/issues/671)) - part of [#669](https://github.com/openwdl/wdl/pull/669).
* Various examples with parsing issues, invalid inputs/outputs, or runtime failures - fixed by correcting syntax and logic ([#701](https://github.com/openwdl/wdl/issues/701)) - part of [#706](https://github.com/openwdl/wdl/pull/706).
* Removed Advanced Task Examples to clearly identify the goals and scope of the testing.  - part of [#706](https://github.com/openwdl/wdl/pull/706).
* Fixed the unit test for `round()` to properly test for round-half-up behavior as described in the specification - fixed by [#715](https://github.com/openwdl/wdl/pull/715).
* Removed Advanced Task Examples to clearly distinguish what is in scope for testing ([#730](https://github.com/openwdl/wdl/issues/730)).
</code></pre></div></div>

<ul>
  <li><strong>Specification Clarifications</strong>:
    <ul>
      <li>Clarification around <code class="language-plaintext highlighter-rouge">File</code> - part of <a href="https://github.com/openwdl/wdl/pull/669">#669</a>.
        <ul>
          <li>The path assigned to a <code class="language-plaintext highlighter-rouge">File</code> is not required to be valid unless and until it is accessed.
            <ul>
              <li>To read from a file, it must exist and be assigned appropriate permissions.</li>
              <li>To write to a file, the parent directory must be assigned appropriate permissions.</li>
            </ul>
          </li>
          <li>Remote files must be treated as read-only.</li>
          <li>A remote file is only required to be valid at the time that the execution engine needs to localize it.</li>
        </ul>
      </li>
    </ul>
  </li>
</ul>

<p>If you find other areas of the specification that you think need improvement, we welcome
<a href="https://github.com/openwdl/wdl/issues">issues</a> and <a href="https://github.com/openwdl/wdl/pulls">pull requests</a>.</p>]]></content><author><name>Venkat Malladi</name></author><category term="wdl" /><category term="bioinformatics" /><category term="workflows" /><summary type="html"><![CDATA[Announcing WDL 1.1.3]]></summary></entry><entry><title type="html">Announcing WDL 1.2.1</title><link href="https://vsmalladi.github.io/openwdl.github.io//wdl/bioinformatics/workflows/announcing-wdl-1-2-1/" rel="alternate" type="text/html" title="Announcing WDL 1.2.1" /><published>2026-02-15T18:00:00+00:00</published><updated>2026-02-15T18:00:00+00:00</updated><id>https://vsmalladi.github.io/openwdl.github.io//wdl/bioinformatics/workflows/announcing-wdl-1-2-1</id><content type="html" xml:base="https://vsmalladi.github.io/openwdl.github.io//wdl/bioinformatics/workflows/announcing-wdl-1-2-1/"><![CDATA[<h1 id="announcing-wdl-121">Announcing WDL 1.2.1</h1>

<p>The <a href="https://openwdl.org/">OpenWDL</a> community is pleased to announce the
release of <a href="https://github.com/openwdl/wdl/blob/wdl-1.2/SPEC.md">Workflow Description Language (WDL)
1.2.1</a>! The full list of issues and PRs can be found in the <a href="https://github.com/openwdl/wdl/milestone/6?closed=1">1.2.1 milestone</a>.</p>

<h2 id="whats-new">What’s new?</h2>

<p><a href="https://github.com/openwdl/wdl/blob/wdl-1.2/SPEC.md">Workflow Description Language (WDL)
1.2.1</a> is a patch release that primarily brings forward specification clarifications, test corrections, and infrastructure improvements that were first introduced in <a href="https://github.com/openwdl/wdl/blob/wdl-1.1/SPEC.md">v1.1.3</a>. Additionally, this patch addresses many issues with the clarity of the specification around <code class="language-plaintext highlighter-rouge">Directory</code> and <code class="language-plaintext highlighter-rouge">join_paths</code>.</p>

<h3 id="testing-infrastructure-and-improvements">Testing Infrastructure and Improvements</h3>

<p>The biggest improvement brought into this release from <a href="https://github.com/openwdl/wdl/blob/wdl-1.1/SPEC.md">v1.1.3</a> is that we have switched our compliance suite to use <a href="https://github.com/openwdl/spectool">spectool</a>. This new tool allows you to parse the examples in a <a href="https://github.com/openwdl/spectool/blob/main/docs/SPEC.md">standardized format</a> and test cases in the spec into discrete testable WDL files that can be verified by your engine of choice.</p>

<h4 id="engine-compatibility">Engine compatibility</h4>

<p>The improved testing infrastructure allows anyone in the community to make a change and have <a href="https://github.com/openwdl/wdl/tree/wdl-1.2/.github/workflows">Github Actions</a> that run for the current major engines:</p>

<ul>
  <li><a href="https://cromwell.readthedocs.io/en/latest/">Cromwell</a></li>
  <li><a href="https://miniwdl.readthedocs.io/en/latest/">miniwdl</a></li>
  <li><a href="https://toil.ucsc-cgl.org/">Toil</a></li>
  <li><a href="https://sprocket.bio/">Sprocket</a></li>
</ul>

<p>We have created <a href="https://github.com/openwdl/wdl/blob/wdl-1.2/README.md#workflow-description-language-wdl">badges</a> that highlight how many of the tests pass for each engine. Full compliance will be at 100% pass rate.</p>

<h3 id="test-case-bug-fixes-and-corrections">Test Case Bug Fixes and Corrections</h3>

<p>Additionally, as we implemented our new Continuous Integration (CI) testing pipeline, we discovered many test cases needed to be fixed or clarified in order to just be executed. Many of these fixes were implemented in <a href="https://github.com/openwdl/wdl/blob/wdl-1.1/SPEC.md">v1.1.3</a> and ported over to this release thanks to <a href="https://github.com/stxue1">@stxue1</a> and <a href="https://github.com/vsmalladi">@vsmalladi</a>, with contributions from <a href="https://github.com/jdidion">@jdidion</a> and reviews from <a href="https://github.com/adamnovak">@adamnovak</a> and <a href="https://github.com/claymcleod">@claymcleod</a>. Below is a summary of some of the big fixes and clarifications.</p>

<ul>
  <li>Fixed examples that didn’t compile in <code class="language-plaintext highlighter-rouge">wdl-tests</code>, including ones that were fixed in <a href="https://github.com/openwdl/wdl/blob/wdl-1.1/SPEC.md">v1.1.3</a> (<a href="https://github.com/openwdl/wdl/pull/702">#702</a>).</li>
  <li>Removed Advanced Task Examples to clearly distinguish what is in scope for testing (<a href="https://github.com/openwdl/wdl/issues/730">#730</a>).</li>
  <li>Fixed <code class="language-plaintext highlighter-rouge">change_extension_task.wdl</code> example to use string interpolation when passing <code class="language-plaintext highlighter-rouge">File</code> to <code class="language-plaintext highlighter-rouge">sub()</code> function (<a href="https://github.com/openwdl/wdl/issues/747">#747</a>).</li>
</ul>

<h3 id="specification-clarifications">Specification Clarifications</h3>

<p>While this release does not introduce new language features, it significantly improves clarity in several areas of the specification. These changes help ensure consistent behavior across engines and remove ambiguities that had led to confusion or inconsistent implementations.</p>

<h4 id="task-and-type-semantics">Task and Type Semantics</h4>

<p>We clarified several aspects of task evaluation and type behavior. Most notably, <code class="language-plaintext highlighter-rouge">task.return_code</code> is now explicitly defined as being available only within the <code class="language-plaintext highlighter-rouge">output</code> section, where it has type <code class="language-plaintext highlighter-rouge">Int</code> (not <code class="language-plaintext highlighter-rouge">Int?</code>). This removes ambiguity about when it can be accessed and whether it may be undefined (<a href="https://github.com/openwdl/wdl/pull/742">#742</a>).</p>

<p>We also clarified that multi-level optionals are not allowed. Optional types must resolve to a concrete underlying type, preventing constructions that were previously underspecified and difficult for engines to handle consistently. For example, <code class="language-plaintext highlighter-rouge">Int??</code> is not a valid type. However, nested optionals within compound types are allowed, such as <code class="language-plaintext highlighter-rouge">Array[String?]?</code>, where each <code class="language-plaintext highlighter-rouge">?</code> applies to a different structural level of the type (<a href="https://github.com/openwdl/wdl/pull/743">#743</a>).</p>

<p>Together, these updates tighten type semantics and make task evaluation rules more predictable.</p>

<h4 id="file-directory-and-path-behavior">File, Directory, and Path Behavior</h4>

<p>A substantial portion of this release focused on clarifying the behavior of <code class="language-plaintext highlighter-rouge">File</code> and <code class="language-plaintext highlighter-rouge">Directory</code> values.</p>

<p>We explicitly stated that <code class="language-plaintext highlighter-rouge">File</code> values cannot refer to directories and <code class="language-plaintext highlighter-rouge">Directory</code> values cannot refer to files—assigning the wrong kind of path is an error. Paths are not required to exist until they are accessed, but when they are accessed, clear rules apply—clarified in <a href="https://github.com/openwdl/wdl/pull/748">#748</a> and <a href="https://github.com/openwdl/wdl/pull/745">#745</a>:</p>

<ul>
  <li>Reading requires the path to exist with appropriate permissions.</li>
  <li>Writing requires the appropriate directory to be writable.</li>
  <li>Remote paths must be treated as read-only and only need to be valid at localization time.</li>
</ul>

<p>We also clarified how paths behave when compared or converted:</p>

<ul>
  <li>When comparing a <code class="language-plaintext highlighter-rouge">File</code> or <code class="language-plaintext highlighter-rouge">Directory</code> to a <code class="language-plaintext highlighter-rouge">String</code>, the string is first coerced and canonicalized.</li>
  <li>Converting a <code class="language-plaintext highlighter-rouge">Directory</code> to a <code class="language-plaintext highlighter-rouge">String</code> does not append a trailing slash.</li>
  <li>The <code class="language-plaintext highlighter-rouge">join_paths</code> function now returns a <code class="language-plaintext highlighter-rouge">String</code> (rather than <code class="language-plaintext highlighter-rouge">File</code>) and expects a <code class="language-plaintext highlighter-rouge">Directory</code> as its first argument in the relevant overloads.</li>
</ul>

<p>Relative path resolution is now more precisely defined as well. Outside the <code class="language-plaintext highlighter-rouge">output</code> section, relative paths resolve relative to the WDL document’s parent directory; inside <code class="language-plaintext highlighter-rouge">output</code>, they resolve relative to the task’s execution directory. Optional files evaluate to <code class="language-plaintext highlighter-rouge">None</code> if the referenced path does not exist.</p>

<p>Finally, we clarified that <code class="language-plaintext highlighter-rouge">disk</code> mount points are ephemeral: they should not pre-exist in the host environment, or must be empty and have sufficient available space if they do (<a href="https://github.com/openwdl/wdl/pull/670">#670</a>).</p>

<h4 id="function-and-runtime-behavior">Function and Runtime Behavior</h4>

<p>Function behavior was clarified in a few important places.</p>

<p>The <code class="language-plaintext highlighter-rouge">sub()</code> function now has formally defined replacement string syntax. Backreferences <code class="language-plaintext highlighter-rouge">\1</code> through <code class="language-plaintext highlighter-rouge">\9</code> are supported, matching the limits of POSIX extended regular expressions. Named capture groups are not currently supported. This removes ambiguity around how replacement strings should be interpreted.</p>

<p>We also clarified <code class="language-plaintext highlighter-rouge">glob()</code> behavior with respect to symlinks (<a href="https://github.com/openwdl/wdl/pull/744">#744</a>):</p>

<ul>
  <li>Symlinks to files are included in results.</li>
  <li>Symlinks to directories are excluded.</li>
  <li>Broken symlinks are included.</li>
</ul>

<p>These updates help ensure that filesystem-related behavior is consistent and predictable across engines.</p>

<h3 id="conclusion">Conclusion</h3>

<p>WDL 1.2.1 is a stabilization release for the 1.2.x line. By incorporating the clarifications and test fixes from v1.1.3 and strengthening the compliance infrastructure, this patch improves consistency across engines and reduces ambiguity in key areas of the specification—particularly around <code class="language-plaintext highlighter-rouge">Directory</code>, path resolution, and <code class="language-plaintext highlighter-rouge">join_paths</code>.</p>

<p>No new language features were introduced, and no existing functionality was changed. Instead, this release focuses on making the specification clearer, the test suite more reliable, and engine behavior more predictable. These improvements help ensure that WDL workflows behave consistently across implementations and are easier to validate and maintain.</p>

<p>Thank you to everyone who contributed to this milestone, including:</p>

<ul>
  <li><a href="https://github.com/stxue1">@stxue1</a></li>
  <li><a href="https://github.com/vsmalladi">@vsmalladi</a></li>
  <li><a href="https://github.com/jdidion">@jdidion</a></li>
  <li><a href="https://github.com/adamnovak">@adamnovak</a></li>
  <li><a href="https://github.com/claymcleod">@claymcleod</a></li>
  <li><a href="https://github.com/peterhuene">@peterhuene</a></li>
  <li><a href="https://github.com/a-frantz">@a-frantz</a></li>
  <li><a href="https://github.com/markjschreiber">@markjschreiber</a></li>
</ul>

<p>and others who participated in discussion, review, and testing.</p>

<p>As always, we welcome community feedback. If you find areas of the specification that could be improved, please open an <a href="https://github.com/openwdl/wdl/issues">issue</a> or submit a <a href="https://github.com/openwdl/wdl/pulls">pull request</a>.</p>]]></content><author><name>Venkat Malladi</name></author><category term="wdl" /><category term="bioinformatics" /><category term="workflows" /><summary type="html"><![CDATA[Announcing WDL 1.2.1]]></summary></entry><entry><title type="html">Announcing WDL 1.3.0</title><link href="https://vsmalladi.github.io/openwdl.github.io//wdl/bioinformatics/workflows/announcing-wdl-1-3-0/" rel="alternate" type="text/html" title="Announcing WDL 1.3.0" /><published>2026-01-10T18:00:00+00:00</published><updated>2026-01-10T18:00:00+00:00</updated><id>https://vsmalladi.github.io/openwdl.github.io//wdl/bioinformatics/workflows/announcing-wdl-1-3-0</id><content type="html" xml:base="https://vsmalladi.github.io/openwdl.github.io//wdl/bioinformatics/workflows/announcing-wdl-1-3-0/"><![CDATA[<p>It’s been a while since our last release! WDL v1.2 introduced features like the <code class="language-plaintext highlighter-rouge">Directory</code> type, multi-line strings, and the <code class="language-plaintext highlighter-rouge">requirements</code>/<code class="language-plaintext highlighter-rouge">hints</code> sections, but that was several years ago. Since then, execution engines have been steadily improving, and <a href="https://github.com/stjude-rust-labs/sprocket">Sprocket</a> recently became the first engine to <a href="https://github.com/openwdl/wdl/blob/wdl-1.2/README.md">fully support the 1.2 spec</a>. With a complete implementation now available, we have the foundation to confidently move forward. Throughout this period, the community has continued to file issues, propose enhancements, and—reasonably—wonder what’s next for WDL.</p>

<p>Today, we’re happy to announce the answer to that question—<a href="https://github.com/openwdl/wdl/blob/wdl-1.3/SPEC.md">WDL v1.3</a>. This release focuses on quality-of-life improvements: features that reduce friction in everyday workflow development and clarifications that make WDL’s behavior more predictable across execution engines. There are no breaking changes, just refinements that address long-standing requests.</p>

<p>We’ll cover the main additions below: <code class="language-plaintext highlighter-rouge">else</code> and <code class="language-plaintext highlighter-rouge">else if</code> clauses for conditional statements, enumeration types, dynamic resource allocation for retrying tasks, and a handful of smaller improvements.</p>

<h2 id="language-ergonomics">Language Ergonomics</h2>

<h3 id="conditional-statements-with-else">Conditional Statements with <code class="language-plaintext highlighter-rouge">else</code></h3>

<p>WDL has always supported conditional blocks via <code class="language-plaintext highlighter-rouge">if</code>, but until now there was no <code class="language-plaintext highlighter-rouge">else</code> clause. To express mutually exclusive branches, you had to write two separate <code class="language-plaintext highlighter-rouge">if</code> statements with negated conditions. WDL v1.3 introduces <code class="language-plaintext highlighter-rouge">else</code> and <code class="language-plaintext highlighter-rouge">else if</code> clauses, as discussed in <a href="https://github.com/openwdl/wdl/issues/268">#268</a> and <a href="https://github.com/openwdl/wdl/issues/697">#697</a> and implemented in <a href="https://github.com/openwdl/wdl/pull/699">#699</a>.</p>

<p>For example, now you can express cascading conditional clauses like so:</p>

<pre><code class="language-wdl">version 1.3

workflow spellcaster {
  input {
    String element  # "Fire", "Ice", or "Lightning"
  }

  if (element == "Fire") {
    String incantation = "fireball"
    Int power = 10
  } else if (element == "Ice") {
    String incantation = "frost nova"
    Int power = 8
  } else if (element == "Lightning") {
    String incantation = "lightning bolt"
    Int power = 12
  }

  # The user may not have provided one of the three choices above,
  # so we have to check if these are defined here.
  if (defined(incantation) &amp;&amp; defined(power)) {
    call cast {
      # Now that we know they're defined, `select_first` won't fail.
      words = select_first([incantation]),
      strength = select_first([power])
    }
  }

  output {
    Float? damage = cast.damage
  }
}

task cast {
  input {
    String words
    Int strength
  }

  command &lt;&lt;&lt;
    echo "Casting '~{words}' with power ~{strength}!" &gt;&amp;2
    awk "BEGIN { printf \"%.2f\", rand() * ~{strength} }"
  &gt;&gt;&gt;

  output {
    Float damage = read_float(stdout())
  }
}
</code></pre>

<h3 id="the-split-function">The <code class="language-plaintext highlighter-rouge">split</code> Function</h3>

<p>Before WDL v1.3, splitting a string on a delimiter required writing a task that shells out to <code class="language-plaintext highlighter-rouge">awk</code> or a similar tool—overhead that’s hard to justify for something so simple. As requested in <a href="https://github.com/openwdl/wdl/issues/553">#553</a>, WDL v1.3 adds a <code class="language-plaintext highlighter-rouge">split</code> standard library function in <a href="https://github.com/openwdl/wdl/pull/729">#729</a>.</p>

<pre><code class="language-wdl">version 1.3

task parse_spell {
  input {
    String incantation  # e.g., "fireball-big-fast"
  }

  Array[String] words = split(incantation, "-")
  String base_spell = words[0]

  command &lt;&lt;&lt;
    echo "Casting ~{base_spell} with ~{length(words)} modifiers"
  &gt;&gt;&gt;

  output {
    String spell = base_spell
    Int power = length(words)
  }
}
</code></pre>

<h3 id="version-compatibility">Version Compatibility</h3>

<p>Previously, WDL enforced strict version matching on imports—a WDL v1.3 workflow couldn’t import a WDL v1.2 task, even though minor versions are backward compatible. This created a problem when contemplating package management extensions to the language. For example, if another organization published a shared task library at v1.2 and you wanted to use it from a v1.3 workflow, you couldn’t. The only workarounds were to fork the library or wait for it to be updated.</p>

<p>In anticipation of package management features coming in a future version of WDL, v1.3 relaxes this requirement in <a href="https://github.com/openwdl/wdl/pull/698">#698</a>. Documents can now import any document with the same major version and a minor version less than or equal to their own. A v1.3 workflow can import v1.2 tasks; a v1.2 workflow cannot import v1.3 tasks.</p>

<h2 id="type-safety">Type Safety</h2>

<h3 id="enumeration-types">Enumeration Types</h3>

<p>Something’s been bothering me about our spell-casting example. The workflow accepts a <code class="language-plaintext highlighter-rouge">String</code> for the element, but spells aren’t arbitrary strings—they’re a fixed set. What if someone passes <code class="language-plaintext highlighter-rouge">"fire"</code> instead of <code class="language-plaintext highlighter-rouge">"Fire"</code>? Or <code class="language-plaintext highlighter-rouge">"Frie"</code> by mistake? None of the conditions match, so nothing gets called. The workflow silently does nothing. And that <code class="language-plaintext highlighter-rouge">defined()</code> check with <code class="language-plaintext highlighter-rouge">select_first()</code> to unwrap the optionals—it works, but it’s not pretty.</p>

<p>Since we have a fixed set of valid options, we can better express this as an enum, which is simply a closed set of choices. WDL v1.3 introduces enumeration types in <a href="https://github.com/openwdl/wdl/pull/695">#695</a>, allowing you to do the following:</p>

<pre><code class="language-wdl">version 1.3

enum Element {
  Fire,
  Ice,
  Lightning
}

workflow spellcaster {
  input {
    Element element
  }

  if (element == Element.Fire) {
    String incantation = "fireball"
    Int power = 10
  } else if (element == Element.Ice) {
    String incantation = "frost nova"
    Int power = 8
  } else if (element == Element.Lightning) {
    String incantation = "lightning bolt"
    Int power = 12
  }

  call cast {
    # We know that the `element` _must_ match one of the enum choices,
    # meaning that these `select_first`s will never fail and we can omit
    # the `defined` checks.
    words = select_first([incantation]),
    strength = select_first([power])
  }

  output {
    Float damage = cast.damage
  }
}

task cast {
  input {
    String words
    Int strength
  }

  command &lt;&lt;&lt;
    echo "Casting '~{words}' with power ~{strength}!" &gt;&amp;2
    awk "BEGIN { printf \"%.2f\", rand() * ~{strength} }"
  &gt;&gt;&gt;

  output {
    Float damage = read_float(stdout())
  }
}
</code></pre>

<p>Now the input is constrained—only <code class="language-plaintext highlighter-rouge">Fire</code>, <code class="language-plaintext highlighter-rouge">Ice</code>, or <code class="language-plaintext highlighter-rouge">Lightning</code> are valid. Typos fail loudly at validation time or input parsing time, not silently at runtime. For example, Sprocket complains if you try to provide a choice that is not one of these at validation time:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>sprocket run enum.wdl <span class="nt">-e</span> spellcaster <span class="nv">element</span><span class="o">=</span><span class="s2">"Water"</span>
<span class="c"># error: type mismatch: expected type `Element`, but found</span>
<span class="c"># type `String`: cannot coerce type `String` to type</span>
<span class="c"># `Element`: variant `Water` not found in enum `Element`</span>
<span class="c"># (variants: `Fire`, `Ice`, `Lightning`)</span>
</code></pre></div></div>

<p>We can improve this example further. Both the incantation and power of each spell are fixed, so why define them separately? Enums in WDL are <em>valued</em>—each choice can carry an associated value of any WDL type, including structs. We can store both properties directly in the enum and extract them with the <code class="language-plaintext highlighter-rouge">value()</code> standard library function:</p>

<pre><code class="language-wdl">version 1.3

struct Spell {
  String incantation
  Int power
}

enum Element {
  Fire = Spell { incantation: "fireball", power: 10 },
  Ice = Spell { incantation: "frost nova", power: 8 },
  Lightning = Spell { incantation: "lightning bolt", power: 12 }
}

workflow spellcaster {
  input {
    Element element
  }

  Spell spell = value(element)

  call cast { spell = spell }

  output {
    Float damage = cast.damage
  }
}

task cast {
  input {
    Spell spell
  }

  command &lt;&lt;&lt;
    echo "Casting '~{spell.incantation}' with power ~{spell.power}!" &gt;&amp;2
    awk "BEGIN { printf \"%.2f\", rand() * ~{spell.power} }"
  &gt;&gt;&gt;

  output {
    Float damage = read_float(stdout())
  }
}
</code></pre>

<p>This pattern is common—a fixed set of choices where each maps to specific values. Valued enums express it concisely and let execution engines provide better validation and error messages.</p>

<h2 id="resilient-workflows">Resilient Workflows</h2>

<h3 id="dynamic-resource-allocation">Dynamic Resource Allocation</h3>

<p>Some tasks fail not because of bugs, but because they need more resources than initially allocated. The fix is often simple: retry with more memory or disk. Before WDL v1.3, the <code class="language-plaintext highlighter-rouge">task</code> variable was only accessible in <code class="language-plaintext highlighter-rouge">command</code> and <code class="language-plaintext highlighter-rouge">output</code> sections. You couldn’t use it in <code class="language-plaintext highlighter-rouge">requirements</code>, <code class="language-plaintext highlighter-rouge">hints</code>, or <code class="language-plaintext highlighter-rouge">runtime</code> sections where resource allocation actually happens. Further, even where it was accessible, you only had access to a limited set of information about the current task (such as the task attempt number in <code class="language-plaintext highlighter-rouge">task.attempt</code>).</p>

<p>As discussed in <a href="https://github.com/openwdl/wdl/issues/696">#696</a>, WDL v1.3 expands the <code class="language-plaintext highlighter-rouge">task</code> variable to be available in these sections and adds <code class="language-plaintext highlighter-rouge">task.previous</code> in <a href="https://github.com/openwdl/wdl/pull/734">#734</a>, which provides direct access to the previous attempt’s computed requirements, allowing you to express a wide array of dynamic retry logic. Last, <code class="language-plaintext highlighter-rouge">task.max_retries</code> appears to have been accidentally omitted from the <code class="language-plaintext highlighter-rouge">task</code> type in WDL v1.2, so it was added in WDL v1.3 (see <a href="https://github.com/openwdl/wdl/issues/732">#732</a> and <a href="https://github.com/openwdl/wdl/pull/733">#733</a>).</p>

<pre><code class="language-wdl">version 1.3

task count_primes {
  input {
    Int max_number
  }

  command &lt;&lt;&lt;
    # Simulate failure on the first two attempts
    if [ ~{task.attempt} -lt 2 ]; then
      echo "Attempt ~{task.attempt}: not enough resources, failing..." &gt;&amp;2
      exit 1
    fi

    # On the third attempt, do the real work
    awk 'BEGIN {
      count = 0
      for (n = 2; n &lt;= ~{max_number}; n++) {
        is_prime = 1
        for (i = 2; i * i &lt;= n; i++) {
          if (n % i == 0) { is_prime = 0; break }
        }
        if (is_prime) count++
      }
      print count
    }'
  &gt;&gt;&gt;

  requirements {
    cpu: task.attempt + 1
    memory: "~{2 ** task.attempt} GB"
    max_retries: 3
  }

  output {
    Int prime_count = read_int(stdout())
  }
}
</code></pre>

<p>On the first attempt, the task requests 1 CPU and 1 GB of memory. If it fails and retries, it increments CPUs and doubles memory—2 CPUs and 2 GB on the second attempt, 3 CPUs and 4 GB on the third attempt, and so on. In this way, the task adapts to what is needed dynamically.</p>

<p>For more complex logic, <code class="language-plaintext highlighter-rouge">task.previous</code> provides direct access to the previous attempt’s computed requirements. Each field (e.g., <code class="language-plaintext highlighter-rouge">task.previous.cpu</code>, <code class="language-plaintext highlighter-rouge">task.previous.memory</code>) is optional since there’s no previous attempt on the first try. This is useful when your retry logic depends on the actual values from the previous attempt—for example, doubling memory when it’s small but capping it once it exceeds a threshold:</p>

<pre><code class="language-wdl">version 1.3

task count_primes {
  input {
    Int max_number
    String starting_memory = "1 GB"
  }

  command &lt;&lt;&lt;
    # Simulate failure on the first two attempts
    if [ ~{task.attempt} -lt 2 ]; then
      echo "Attempt ~{task.attempt}: not enough resources, failing..." &gt;&amp;2
      exit 1
    fi

    # On the third attempt, do the real work
    awk 'BEGIN {
      count = 0
      for (n = 2; n &lt;= ~{max_number}; n++) {
        is_prime = 1
        for (i = 2; i * i &lt;= n; i++) {
          if (n % i == 0) { is_prime = 0; break }
        }
        if (is_prime) count++
      }
      print count
    }'
  &gt;&gt;&gt;

  requirements {
    cpu: task.attempt + 1
    memory: (
      # First attempt: use `starting_memory` parameter
      if !defined(task.previous.memory) then starting_memory
      # Under `8 GB`: double it
      else if select_first([task.previous.memory]) &lt;= 8000000000
        then "~{floor(select_first([task.previous.memory]) / 500000000)} GB"
      # Above `8 GB`: cap at `16 GB`
      else "16 GB"
    )
    max_retries: 3
  }

  output {
    Int prime_count = read_int(stdout())
  }
}
</code></pre>

<h2 id="stability">Stability</h2>

<p>Beyond new features, WDL v1.3 includes clarifications that make the language more predictable across implementations.</p>

<h3 id="path-resolution-and-file-existence">Path Resolution and File Existence</h3>

<p>Prior to WDL v1.3, the specification was ambiguous about how <code class="language-plaintext highlighter-rouge">File</code> and <code class="language-plaintext highlighter-rouge">Directory</code> declarations behave. As reported in <a href="https://github.com/openwdl/wdl/issues/673">#673</a> and <a href="https://github.com/openwdl/wdl/issues/676">#676</a>, identical code could produce different results depending on where it appeared: a declaration like <code class="language-plaintext highlighter-rouge">Array[File?] files = ["example.txt"]</code> might behave unexpectedly in private declarations versus output sections.</p>

<p>The clarifications in <a href="https://github.com/openwdl/wdl/pull/735">#735</a> resolve this by explicitly defining:</p>

<ul>
  <li>
    <p><strong>What relative paths are relative to</strong>: Outside the <code class="language-plaintext highlighter-rouge">output</code> section, relative paths resolve relative to the WDL document’s parent directory. Inside the <code class="language-plaintext highlighter-rouge">output</code> section, they resolve relative to the task’s execution directory.</p>
  </li>
  <li>
    <p><strong>When files must exist</strong>: Files and directories must exist at declaration evaluation time, not access time. If the specified path does not exist, it is an error—unless the declaration is optional.</p>
  </li>
  <li>
    <p><strong>Optional file semantics</strong>: <code class="language-plaintext highlighter-rouge">File?</code> and <code class="language-plaintext highlighter-rouge">Directory?</code> declarations evaluate to <code class="language-plaintext highlighter-rouge">None</code> when the referenced path doesn’t exist. This behavior is now consistent across all declaration contexts.</p>
  </li>
</ul>

<p>These clarifications ensure that workflows behave the same regardless of which compliant engine runs them.</p>

<h2 id="looking-forward">Looking Forward</h2>

<p>We’ve enjoyed getting back to improving the language, and there’s more to come. We expect one more minor release—WDL 1.4—to continue addressing community requests before turning our attention to WDL 2.0, where larger changes to the language will be proposed.</p>

<p>If you want to try these features today, Sprocket already supports WDL v1.3 in full—you can learn how to install it at <a href="https://sprocket.bio/installation.html">sprocket.bio</a>. To check which execution engines support v1.3, see the compliance status at the top of the <a href="https://github.com/openwdl/wdl/blob/wdl-1.3/README.md">README</a>. If you have ideas for future versions, run into issues, or just want to follow along with development, join the <a href="https://openwdl.slack.com">OpenWDL Slack</a> or open an issue on the <a href="https://github.com/openwdl/wdl">specification repository</a>.</p>]]></content><author><name>Clay McLeod</name></author><category term="wdl" /><category term="bioinformatics" /><category term="workflows" /><summary type="html"><![CDATA[It’s been a while since our last release! WDL v1.2 introduced features like the Directory type, multi-line strings, and the requirements/hints sections, but that was several years ago. Since then, execution engines have been steadily improving, and Sprocket recently became the first engine to fully support the 1.2 spec. With a complete implementation now available, we have the foundation to confidently move forward. Throughout this period, the community has continued to file issues, propose enhancements, and—reasonably—wonder what’s next for WDL.]]></summary></entry><entry><title type="html">WDL Survey Report</title><link href="https://vsmalladi.github.io/openwdl.github.io//wdl/bioinformatics/workflows/wdl-survery/" rel="alternate" type="text/html" title="WDL Survey Report" /><published>2025-02-27T21:24:15+00:00</published><updated>2025-02-27T21:24:15+00:00</updated><id>https://vsmalladi.github.io/openwdl.github.io//wdl/bioinformatics/workflows/wdl-survery</id><content type="html" xml:base="https://vsmalladi.github.io/openwdl.github.io//wdl/bioinformatics/workflows/wdl-survery/"><![CDATA[<h2 id="introduction">Introduction</h2>

<p>In January 2024, we sent our first WDL Usage and Adoption Survey aimed to gather insights and feedback from the <a href="https://openwdl.org/">WDL</a> user community. The survey received responses from professionals working in academia and the biotech/pharma industries. By sharing these findings and trends, we aim to drive the evolution of the <a href="https://github.com/openwdl/wdl">WDL spec</a>, enable the community of researchers and developers to build new innovations and collaborations around WDL best practices. This report summarizes the key findings and trends observed from the survey responses.</p>

<h2 id="key-findings">Key Findings</h2>

<h3 id="community">Community</h3>

<p>The WDL community is growing. Our community primarily considers themselves either a <strong>bioinformatician (47%) or software engineer (37%)</strong> (Fig 1). Of these users, 77% identify as from academia (Fig 2). While the WDL spec has been around for nearly a decade, it is clear that our community is growing. We see that <strong>31% of users have picked it up in the last 1-3 years</strong> (Fig 3).</p>

<p><img src="/assets/images/survey_jan2024/demographics.png" alt="Fig 1" />
<em>Fig 1</em></p>

<p><img src="/assets/images/survey_jan2024/industry.png" alt="Fig 2" />
<em>Fig 2</em></p>

<p><img src="/assets/images/survey_jan2024/wdl_familarity.png" alt="Fig 3" />
<em>Fig 3</em></p>

<p>To build and foster a sense of community, we wanted to know how our users interact with each other. Engagement with the WDL community is occasional at best (Fig 4), with the majority of users using platforms like GitHub Discussions or WDL Slack (Fig 5). Users expressed a desire for more opportunities to connect and share knowledge with fellow WDL users.</p>

<p><img src="/assets/images/survey_jan2024/engagement.png" alt="Fig 4" />
<em>Fig 4</em></p>

<p><img src="/assets/images/survey_jan2024/wdl_forums.png" alt="Fig 5" />
<em>Fig 5</em></p>

<h3 id="workflow-deployment-and-usage">Workflow Deployment and Usage</h3>

<p>As important as a sense of community, it is important to highlight how and where our users run their workflows. The majority of participants identified <strong>Cromwell (62%) as the leading WDL engine</strong>, followed by MiniWDL (27%) and a variety of other engines (Fig 6). Over 76% of respondents indicated that they primarily run their workflows in the cloud natively or through platforms such as Terra, DNANexus, and Seven Bridges, which run on multiple cloud infrastructures (Fig 7). If they use the cloud natively, users overwhelmingly choose GCP (<strong>61%</strong>) over the other cloud providers (Fig 8).</p>

<p><img src="/assets/images/survey_jan2024/engines.png" alt="Fig 6" />
<em>Fig 6</em></p>

<p><img src="/assets/images/survey_jan2024/platforms.png" alt="Fig 7" />
<em>Fig 7</em></p>

<p><img src="/assets/images/survey_jan2024/clouds.png" alt="Fig 8" />
<em>Fig 8</em></p>

<h3 id="workflow-development-and-validation">Workflow Development and Validation</h3>

<p>Most users write their own WDL workflows. However, with a growing community, we find that many users look for examples or already developed workflows. Users tend to find workflows on <strong>GitHub (48%)</strong>, BioWDL or WARP, or on Dockstore (40%) (Fig 9). When developing workflows, <strong>validation and linting tools are widely used, 80% of users rely on tools like MiniWDL and Womtool</strong> (Fig 10). As with any developer, WDL users have a wide range of languages they prefer to write in for calling their tools. The most commonly used programming languages with WDL are <strong>Python (36%), Bash (31%), and R (16%)</strong> (Fig 11).</p>

<p><img src="/assets/images/survey_jan2024/workflow_finding.png" alt="Fig 9" />
<em>Fig 9</em></p>

<p><img src="/assets/images/survey_jan2024/lint.png" alt="Fig 10" />
<em>Fig 10</em></p>

<p><img src="/assets/images/survey_jan2024/programming.png" alt="Fig 11" />
<em>Fig 11</em></p>

<h2 id="future-of-wdl">Future of WDL</h2>

<p>The future of WDL is seen with mixed opinions. While <strong>50%</strong> of users expect their usage of WDL to stay the same, <strong>19%</strong> foresee increasing usage, and another <strong>22%</strong> foresee switching to another workflow language (Fig 12).</p>

<p><img src="/assets/images/survey_jan2024/wdl_evolution.png" alt="Fig 12" />
<em>Fig 12</em></p>

<p>Desired features for future versions include:</p>

<ul>
  <li>Better support for scattering with dynamic load balancing</li>
  <li>Improved linters and real-time debuggers for IDEs</li>
  <li>More comprehensive conditional support</li>
</ul>

<p>Additionally, users would like to see an increase in tutorials, best practice guides, and example workflows.</p>

<h2 id="conclusion">Conclusion</h2>

<p>The WDL Usage and Adoption Survey provides valuable insights into the current state of WDL usage and adoption. 
The findings highlight the strengths and areas for improvement, offering guidance for future development and support. 
By addressing the community’s needs and preferences, WDL can continue to evolve and support the bioinformatics community effectively. 
We acknowledge that this survey doesn’t capture the full community perspectives. As a result, over the next couple of months we plan on reaching out more to the community and then conducting another survey in the later half of the year.</p>

<h2 id="future-of-wdl-1">Future of WDL</h2>
<p>The <a href="https://github.com/openwdl/governance/blob/main/README.md">WDL Governance Committee</a> is considering this feedback. As
part of our discussions we are aiming to increase community engagement over the next few months through <a href="https://join.slack.com/t/openwdl/shared_invite/zt-ctmj4mhf-cFBNxIiZYs6SY9HgM9UAVw">Slack</a> and <a href="https://github.com/openwdl/">WDL git repo</a>.</p>]]></content><author><name>Venkat Malladi</name></author><category term="wdl" /><category term="bioinformatics" /><category term="workflows" /><summary type="html"><![CDATA[Introduction]]></summary></entry><entry><title type="html">Sprocket</title><link href="https://vsmalladi.github.io/openwdl.github.io//wdl/bioinformatics/workflows/vscode/lint/announcing-sprocket/" rel="alternate" type="text/html" title="Sprocket" /><published>2024-09-19T21:24:15+00:00</published><updated>2024-09-19T21:24:15+00:00</updated><id>https://vsmalladi.github.io/openwdl.github.io//wdl/bioinformatics/workflows/vscode/lint/announcing-sprocket</id><content type="html" xml:base="https://vsmalladi.github.io/openwdl.github.io//wdl/bioinformatics/workflows/vscode/lint/announcing-sprocket/"><![CDATA[<h1 id="introducing-sprocket">Introducing Sprocket</h1>

<p>We are excited to announce <strong>Sprocket</strong>, a validator and linter for the Workflow Description Language (WDL). Beyond just validation and linting, Sprocket is under active development towards becoming a workflow execution engine for bioinformatics and computational research. Sprocket uses WDL as it’s workflow language of choice, making it a valuable addition to the growing ecosystem of WDL tools.</p>

<h2 id="what-is-sprocket">What is Sprocket?</h2>

<p>Sprocket is written in Rust. The code that drives Sprocket is split across the <a href="https://github.com/stjude-rust-labs/wdl"><code class="language-plaintext highlighter-rouge">wdl</code></a> family of crates, the <a href="https://github.com/stjude-rust-labs/sprocket"><code class="language-plaintext highlighter-rouge">sprocket</code></a> command line tool, and the <a href="https://marketplace.visualstudio.com/items?itemName=stjude-rust-labs.sprocket-vscode">Visual Studio Code extension</a>.</p>

<p>Sprocket aims for the following:</p>

<ul>
  <li><strong>WDL Compatibility</strong>: Full support for workflows written in WDL, allowing users to define complex workflows in a readable and intuitive format.</li>
  <li><strong>Lightweight and Fast</strong>: Optimized for speed and minimal resource usage, Sprocket is a perfect fit for small-to-medium-sized computational projects.</li>
  <li><strong>Flexible Deployment</strong>: Sprocket can run on local machines, clusters, and cloud environments, giving users the freedom to scale their workflows as needed.</li>
  <li><strong>Open-Source</strong>: Developed under an open-source license, Sprocket encourages contributions from the community to extend its capabilities.</li>
</ul>

<h2 id="why-use-sprocket">Why Use Sprocket?</h2>

<p>Sprocket aims at providing a minimal yet robust alternative for testing and running WDL workflows.</p>

<ul>
  <li><strong>Simplicity</strong>: For users who need to run WDL workflows quickly without complex infrastructure setup, Sprocket offers a straightforward solution.</li>
  <li><strong>Speed</strong>: Sprocket is optimized to run workflows with low overhead, helping users execute their tasks faster and more efficiently.</li>
  <li><strong>Community-Driven</strong>: As an open-source project, Sprocket is actively developed and improved by its community, making it adaptable to the needs of users in bioinformatics and beyond.</li>
</ul>

<h2 id="vs-code-extension-for-sprocket">VS Code Extension for Sprocket</h2>

<p>To streamline the workflow development process, <strong>Sprocket</strong> provides a dedicated <strong>Visual Studio Code extension</strong>. This extension integrates Sprocket directly into the popular code editor, offering a powerful environment for writing, running, and debugging WDL workflows.</p>

<p>Here are some of the features the VS Code extension offers:</p>

<ul>
  <li><strong>Syntax Highlighting</strong>: The extension provides WDL syntax highlighting, making your code more readable and easier to navigate.</li>
  <li><strong>Auto-completion</strong>: It supports auto-completion for WDL tasks, inputs, and outputs, helping you write WDL scripts faster and with fewer errors.</li>
  <li><strong>Integrated Workflow Execution</strong>: You can execute Sprocket workflows directly within VS Code, eliminating the need to switch between the editor and the terminal.</li>
  <li><strong>Real-time Error Checking</strong>: Catch issues in your WDL code as you write with integrated real-time error checking.</li>
  <li><strong>Output Logs</strong>: View detailed execution logs within the VS Code interface, making debugging faster and more intuitive.</li>
</ul>

<h3 id="getting-started-with-the-vs-code-extension">Getting Started with the VS Code Extension</h3>

<p>To begin using the Sprocket VS Code extension, follow these simple steps:</p>

<ol>
  <li><strong>Install the Extension</strong>: Open Visual Studio Code, navigate to the Extensions tab, and search for “Sprocket.” Install the extension from the marketplace.</li>
  <li><strong>Configure Sprocket</strong>: Set up the Sprocket executable path by going to your VS Code settings and pointing to the Sprocket installation on your machine.</li>
  <li><strong>Run WDL Workflows</strong>: Open a WDL file in VS Code, and you’ll see the Sprocket toolbar to execute and monitor workflows directly from the editor.</li>
</ol>

<p>For more detailed instructions, you can follow the official <a href="https://stjude-rust-labs.github.io/sprocket/vscode/getting-started.html">Getting Started Guide for VS Code</a>.</p>

<h2 id="getting-started-with-sprocket">Getting Started with Sprocket</h2>

<p>Interested in trying out Sprocket for your next project? Head over to the <a href="https://stjude-rust-labs.github.io/sprocket/overview.html">official Sprocket documentation</a> for detailed installation instructions and usage guides. Whether you are working on local workflows or deploying large-scale computations, Sprocket’s flexibility ensures you can adapt it to fit your needs.</p>

<h2 id="whats-next">What’s Next?</h2>

<p>Sprocket is under active development, and we welcome contributions from the community! Whether you want to suggest new features, report bugs, or contribute code, check out our <a href="https://github.com/stjude-rust-labs/sprocket">GitHub repository</a> and join the conversation on the OpenWDL <a href="https://join.slack.com/t/openwdl/shared_invite/zt-ctmj4mhf-cFBNxIiZYs6SY9HgM9UAVw">Slack</a> and discuss in <code class="language-plaintext highlighter-rouge">#sprocket</code> channel.</p>

<h2 id="conclusion">Conclusion</h2>

<p>Sprocket is a new fast, lightweight, and user-friendly WDL engine designed to make workflow execution easier and more efficient. With a focus on simplicity and performance, Sprocket is a great choice for anyone working with WDL workflows, from small research projects to large-scale bioinformatics pipelines.</p>]]></content><author><name>Venkat Malladi</name></author><category term="wdl" /><category term="bioinformatics" /><category term="workflows" /><category term="vscode" /><category term="lint" /><summary type="html"><![CDATA[Introducing Sprocket]]></summary></entry><entry><title type="html">Announcing WDL 1.2.0</title><link href="https://vsmalladi.github.io/openwdl.github.io//wdl/bioinformatics/workflows/announcing-wdl-1-2-0/" rel="alternate" type="text/html" title="Announcing WDL 1.2.0" /><published>2024-05-29T17:02:15+00:00</published><updated>2024-05-29T17:02:15+00:00</updated><id>https://vsmalladi.github.io/openwdl.github.io//wdl/bioinformatics/workflows/announcing-wdl-1-2-0</id><content type="html" xml:base="https://vsmalladi.github.io/openwdl.github.io//wdl/bioinformatics/workflows/announcing-wdl-1-2-0/"><![CDATA[<h1 id="announcing-wdl-120-release">Announcing WDL 1.2.0 Release</h1>

<p>The <a href="https://openwdl.org/">OpenWDL</a> community is pleased to announce the release of <a href="https://github.com/openwdl/wdl/blob/wdl-1.2/SPEC.md">Workflow Description Language (WDL) 1.2.0</a>! This update introduces several new features and enhancements aimed at improving workflow definition and execution.</p>

<h2 id="support-for-directory-inputs-and-outputs">Support for Directory Inputs and Outputs</h2>

<p>From the very beginning, WDL has had first-class support for files as inputs to, and outputs from, workflows and tasks. In WDL 1.2, the new <a href="https://github.com/openwdl/wdl/blob/wdl-1.2/SPEC.md#files-and-directories"><code class="language-plaintext highlighter-rouge">Directory</code></a> type brings first-class support for directories as well.</p>

<pre><code class="language-wdl">version 1.2

# concatenate the contents of all files in a directory
task directory_example {
    input {
        Directory dir
    }

    command &lt;&lt;&lt;
    for file in ~{dir}; do
      cat $file
    done
    &gt;&gt;&gt;

    output {
        File concatenated = stdout()
    }
}
</code></pre>

<p>When a task has a <code class="language-plaintext highlighter-rouge">Directory</code>-typed input parameter, the directory that is passed as a value will be “staged in” to the task’s execution environment in the same way that files are staged for <code class="language-plaintext highlighter-rouge">File</code>-typed input parameters. The execution engine determines how to make the contents of the directory available (e.g., symlinking or copying local files, or downloading remote files), and then it updates the value of the parameter to contain the path to where the directory was staged.</p>

<p>Similarly, when a task has a <code class="language-plaintext highlighter-rouge">Directory</code>-typed output parameter, the local directory path assigned to it will be “staged out” after the task has completed successfully.</p>

<pre><code class="language-wdl">version 1.2

task directory_output {
    command &lt;&lt;&lt;
    mkdir out
    for n in {1..10}; do
      echo $n &gt; out/file.$n
    done
    &gt;&gt;&gt;

    output {
        Directory dir = "out/"
    }
}
</code></pre>

<p>Just like a file, the contents of a directory can change in between executions of a workflow. However, unlike a file, it is not always easy (or even possible) for an execution engine to determine if the contents of a directory have changed. For example, cloud object storage services (such as AWS S3 or Azure Blob) do not provide a checksum for folders the same way they do for files. This means that the reproducibility of a workflow that takes a directory input cannot be guaranteed, which means that job caching cannot be used.</p>

<p>WDL 1.2 provides a solution to this reproducibility problem with the <a href="https://github.com/openwdl/wdl/blob/wdl-1.2/SPEC.md#extended-filedirectory-inputoutput-format">Extended File/Directory Input/Output Format</a>. An execution engine that supports this format will accept a <a href="https://github.com/openwdl/wdl/blob/wdl-1.2/SPEC.md#json-input-format">JSON input file</a> in which a directory input is specified as a listing of the files within that directory. The execution engine will only localize the listed files, and it will fail with an error if any of the listed files do not exist.</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"wf.indir"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"basename"</span><span class="p">:</span><span class="w"> </span><span class="s2">"foo"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"listing"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
      </span><span class="p">{</span><span class="w">
        </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"File"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"location"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/mnt/data/results/foo/bar.txt"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"basename"</span><span class="p">:</span><span class="w"> </span><span class="s2">"something_else.txt"</span><span class="w">
      </span><span class="p">},</span><span class="w">
      </span><span class="p">{</span><span class="w">
        </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Directory"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"basename"</span><span class="p">:</span><span class="w"> </span><span class="s2">"baz"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"listing"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
          </span><span class="p">{</span><span class="w">
            </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"File"</span><span class="p">,</span><span class="w">
            </span><span class="nl">"location"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/home/fred/qux.fa"</span><span class="w">
          </span><span class="p">}</span><span class="w">
        </span><span class="p">]</span><span class="w">
      </span><span class="p">}</span><span class="w">
    </span><span class="p">]</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p>This can even be used to construct a directory at runtime that consists of files from disparate sources.</p>

<h2 id="requirements-and-hints">Requirements and Hints</h2>

<p>Previously the <code class="language-plaintext highlighter-rouge">runtime</code> section of a WDL task has been used to declare the resources that the task requires at runtime, such as the number of CPUs or amount of memory. However, the <code class="language-plaintext highlighter-rouge">runtime</code> section has two major issues that have become clear over time:</p>

<ol>
  <li>It allows arbitrary attributes that may not be supported by all WDL execution engines.</li>
  <li>It allows mixing of “requirements” - resources that the task must have in order to run - and “hints” - attributes that may be used by the execution engine to optimize the execution of the task, but which are not strictly required.</li>
</ol>

<p>In WDL 1.2, both of these issues are addressed by the introduction of two new sections - <a href="https://github.com/openwdl/wdl/blob/wdl-1.2/SPEC.md#-requirements-section"><code class="language-plaintext highlighter-rouge">requirements</code></a> and <a href="https://github.com/openwdl/wdl/blob/wdl-1.2/SPEC.md#-hints-section"><code class="language-plaintext highlighter-rouge">hints</code></a> - that replace the <code class="language-plaintext highlighter-rouge">runtime</code> section. The <code class="language-plaintext highlighter-rouge">requirements</code> section contains a controlled set of attributes that are hard requirements of the task - if any of them cannot be satisfied, then the task fails. The <code class="language-plaintext highlighter-rouge">hints</code> section, on the other hand, specifies requested resources that the execution may or may not honor, depending on its capabilities. While there are some reserved hints, the user is free to specify additional arbitrary hints that may be specific to an execution engine, a cloud environment, or an HPC job scheduler. The task must be written such that it can complete successfully even if some of its hints are not satisfied.</p>

<pre><code class="language-wdl">version 1.2

task dynamic_container {
  input {
    String image_tag = "latest"
    String ubuntu_release
  }

  command &lt;&lt;&lt;
    cat /etc/*-release | grep DISTRIB_CODENAME | cut -f 2 -d '=' &gt; ubuntu_release
    nvcc -V &gt; cuda_version
  &gt;&gt;&gt;
  
  output {
    String is_expected_release = ubuntu_release == read_string("ubuntu_release")
    String cuda_version = read_string("cuda_version")
  }

  requirements {
    container: "nvidia/cuda:~{image_tag}"
    gpu: true
  }

  hints {
    gpu: 2
  }
}
</code></pre>

<p>WDL 1.2 adds a new <code class="language-plaintext highlighter-rouge">fpga</code> requirement. Similar to <code class="language-plaintext highlighter-rouge">gpu</code>, the <code class="language-plaintext highlighter-rouge">fpga</code> requirement specifies whether the task requires at least one FPGA resource. This is important to support bioinformatics tools such as Illumina’s DRAGEN, which uses FPGAs for accelerated alignment and variant calling. WDL 1.2 also adds the <code class="language-plaintext highlighter-rouge">disks</code>, <code class="language-plaintext highlighter-rouge">gpu</code>, <code class="language-plaintext highlighter-rouge">fpga</code> reserved hints, which enable workflow authors to provide more specific resource requests, such as a specific type of disk or model of GPU.</p>

<p>Requirements and hints represent resource requests to the execution engine, which has some flexibility in how it satisfies them. For example, a workflow author may specify a <code class="language-plaintext highlighter-rouge">memory: "6GiB"</code> requirement, but the execution engine running the workflow may only be able to provision memory amounts in powers-of-two, so the execution environment would actually have 8 GiB of memory. When writing a task, it can be useful (or even necessary) to know what resources are actually available at runtime. While it is possible to determine the available resources using tools such as <code class="language-plaintext highlighter-rouge">nproc</code> and <code class="language-plaintext highlighter-rouge">free</code>, such tools are sometimes specific to the operating system, and their output may require parsing. WDL 1.2 solves this issue with the new implicit <a href="https://github.com/openwdl/wdl/blob/wdl-1.2/SPEC.md#runtime-access-to-requirements-hints-and-metadata"><code class="language-plaintext highlighter-rouge">task</code> object</a> that is available within the <code class="language-plaintext highlighter-rouge">command</code> and <code class="language-plaintext highlighter-rouge">output</code> sections and provides the runtime values for all requirements, as well as access to the task’s metadata.</p>

<p>Another new addition in WDL 1.2 is the <a href="https://github.com/openwdl/wdl/blob/wdl-1.2/SPEC.md#workflow-hints">workflow <code class="language-plaintext highlighter-rouge">hints</code></a> section, which is used to specify hints that apply to all tasks in a workflow or to the orchestration of the workflow itself. Workflow hints used to be specified in the <code class="language-plaintext highlighter-rouge">meta</code> section, but this behavior is now deprecated.</p>

<p>Currently, the only reserved workflow hint is <code class="language-plaintext highlighter-rouge">allow_nested_inputs</code>, which is a <code class="language-plaintext highlighter-rouge">boolean</code> value that, when set to <code class="language-plaintext highlighter-rouge">true</code>, allows the user to set or override at runtime the values of optional task and subworkflow inputs (assuming the execution engine supports this option).</p>

<p>Note that, previously, <code class="language-plaintext highlighter-rouge">allow_nested_inputs</code> also applied to required task/subworkflow inputs, but that behavior is now deprecated. Required inputs must always be set in the <code class="language-plaintext highlighter-rouge">call</code> inputs and/or have a default value.</p>

<h2 id="new-and-improved-standard-library-functions">New and Improved Standard Library Functions</h2>

<p>WDL 1.2 introduces several new functions to the standard library, as well as improvements to some existing functions.</p>

<p>The <a href="https://github.com/openwdl/wdl/blob/wdl-1.2/SPEC.md#-join_paths"><code class="language-plaintext highlighter-rouge">join_paths</code></a> function is now the preferred way to concatenate paths (instead of using the <code class="language-plaintext highlighter-rouge">+</code> operator).</p>

<pre><code class="language-wdl">version 1.2

task resolve_paths_task {
  input {
    File abs_file = "/usr"
    String abs_str = "/usr"
    String rel_dir_str = "bin"
    File rel_file = "echo"
    File rel_dir_file = "mydir"
    String rel_str = "mydata.txt"
  }

  # these are all equivalent to '/usr/bin/echo'
  File bin1 = join_paths(abs_file, [rel_str_dir, rel_file])
  File bin2 = join_paths(abs_str, [rel_str_dir, rel_file])
  File bin3 = join_paths([abs_str, rel_str_dir, rel_file])
  
  # the default behavior is that this resolves to 
  # '&lt;working dir&gt;/mydir/mydata.txt'
  File data = join_paths(rel_dir_file, rel_str)
  
  # this resolves to '&lt;working dir&gt;/bin/echo', which is non-existent
  File doesnt_exist = join_paths([rel_dir_str, rel_file])
  command &lt;&lt;&lt;
    mkdir ~{rel_dir_file}
    ~{bin1} -n "hello" &gt; ~{data}
  &gt;&gt;&gt;

  output {
    Boolean bins_equal = (bin1 == bin2) &amp;&amp; (bin1 == bin3)
    String result = read_string(data)
    File? missing_file = doesnt_exist
  }
  
  runtime {
    container: "ubuntu:latest"
  }
}
</code></pre>

<p>The new <a href="https://github.com/openwdl/wdl/blob/wdl-1.2/SPEC.md#-matches"><code class="language-plaintext highlighter-rouge">matches</code></a> and <a href="https://github.com/openwdl/wdl/blob/wdl-1.2/SPEC.md#-find"><code class="language-plaintext highlighter-rouge">find</code></a> functions perform pattern matching on a <code class="language-plaintext highlighter-rouge">String</code>. The difference between these functions is that <code class="language-plaintext highlighter-rouge">matches</code> will tell you if there is at least one pattern match in the string, while <code class="language-plaintext highlighter-rouge">find</code> will return the contents of the first match.</p>

<pre><code class="language-wdl">version 1.2

workflow contains_string {
  input {
    File fastq = "HG002_R1.fq.gz"
  }

  output {
    String sample_id = find(basename(fastq), "[^_]+")
    Boolean is_compressed = matches(basename(fastq), "\\.(gz|zip|zstd)")
    Boolean is_read1 = matches(basename(fastq), "_R1")
  }
}
</code></pre>

<p>The <a href="https://github.com/openwdl/wdl/blob/wdl-1.2/SPEC.md#-contains"><code class="language-plaintext highlighter-rouge">contains</code></a> function checks for the existence of a value in an array.</p>

<pre><code class="language-wdl">version 1.2

task null_sample {
  command &lt;&lt;&lt;
  echo "Sample array contains a null value!"
  &gt;&gt;&gt;
}

task missing_sample {
  input {
    String name
  }

  command &lt;&lt;&lt;
  echo "Sample ~{name} is missing!"
  &gt;&gt;&gt;
}

workflow test_contains {
  input {
    Array[String?] samples
    String name
  }

  Boolean has_null = contains(samples, None)
  if (has_null) {
    call null_sample
  }
  
  Boolean has_missing = !contains(samples, name)
  if (has_missing) {
    call missing_sample { input: name }
  }

  output {
    Boolean samples_are_valid = !(has_null || has_missing)
  }
}
</code></pre>

<p>The <a href="https://github.com/openwdl/wdl/blob/wdl-1.2/SPEC.md#-chunk"><code class="language-plaintext highlighter-rouge">chunk</code></a> function splits an array up into equal-sized chunks. This is useful for scattering over batches of inputs.</p>

<pre><code class="language-wdl">version 1.2

workflow chunk_array {
  Array[String] s1 = ["a", "b", "c", "d", "e", "f"]
  Array[String] s2 = ["a", "b", "c", "d", "e"]
  Array[String] s3 = ["a", "b"]
  Array[String] s4 = []
  
  scatter (a in chunk(s1, 3)) {
    String concat = sep("", a)
  }

  output {
    Boolean is_reversible = s1 == flatten(chunk(s1, 3))
    Array[Array[String]] o1 = chunk(s1, 3)
    Array[Array[String]] o2 = chunk(s2, 3)
    Array[Array[String]] o3 = chunk(s3, 3)
    Array[Array[String]] o4 = chunk(s4, 3)
    Array[String] concats = concat
  }
}
</code></pre>

<p>The <a href="https://github.com/openwdl/wdl/blob/wdl-1.2/SPEC.md#keys"><code class="language-plaintext highlighter-rouge">keys</code></a> function can now be used to get the names of members in an <code class="language-plaintext highlighter-rouge">Object</code> or <code class="language-plaintext highlighter-rouge">Struct</code> in addition to the keys in a <code class="language-plaintext highlighter-rouge">Map</code>.</p>

<p>The <a href="https://github.com/openwdl/wdl/blob/wdl-1.2/SPEC.md#-contains_key"><code class="language-plaintext highlighter-rouge">contains_key</code></a> function is used to check for the existence of a key in a <code class="language-plaintext highlighter-rouge">Map</code> or a member in an <code class="language-plaintext highlighter-rouge">Object</code>, or <code class="language-plaintext highlighter-rouge">Struct</code>. This function has a variant that takes an <code class="language-plaintext highlighter-rouge">Array[String]</code> of key names and performs a recursive search on a nested compound type.</p>

<pre><code class="language-wdl">version 1.2

struct Person {
  String name
  Map[String, String]? details
}

workflow test_contains_key {
  input {
    Person person
  }

  output {
    String? phone = p1.details["phone"] if contains_key(person, ["details", "phone"]) else None
  }
}
</code></pre>

<p>The <a href="https://github.com/openwdl/wdl/blob/wdl-1.2/SPEC.md#select_first"><code class="language-plaintext highlighter-rouge">select_first</code></a> function now accepts an optional section parameter, a default value to use if the array does not have any non-<code class="language-plaintext highlighter-rouge">None</code> values.</p>

<pre><code class="language-wdl">version 1.2

workflow test_select_first {
  output {
    # both of these statements evaluate to 5
    Int fiveA = select_first([], 5)
    Int fiveB = select_first([None], 5)
  }
}
</code></pre>

<p>The <a href="https://github.com/openwdl/wdl/blob/wdl-1.2/SPEC.md#size"><code class="language-plaintext highlighter-rouge">size</code></a> function now accepts all compound value inputs (i.e., <code class="language-plaintext highlighter-rouge">Pair</code>, <code class="language-plaintext highlighter-rouge">Map</code>, <code class="language-plaintext highlighter-rouge">Struct</code>, and <code class="language-plaintext highlighter-rouge">Object</code>, in addition to <code class="language-plaintext highlighter-rouge">Array</code>) and computes the total size of all files contained within the value to any level of nesting.</p>

<pre><code class="language-wdl">version 1.2

task file_sizes {
  command &lt;&lt;&lt;
    printf "this file is 22 bytes\n" &gt; created_file
  &gt;&gt;&gt;

  File? missing_file = None

  output {
    File created_file = "created_file"
    Map[String, Pair[Int, File]] nested = {
      "a": (10, created_file),
      "b": (50, missing_file)
    }
    Float nested_bytes = size(nested)
  }
  
  requirements {
    container: "ubuntu:latest"
  }
}
</code></pre>

<p>The <a href="https://github.com/openwdl/wdl/blob/wdl-1.2/SPEC.md#length"><code class="language-plaintext highlighter-rouge">length</code></a> function also now accepts more types or arguments - <code class="language-plaintext highlighter-rouge">String</code>, <code class="language-plaintext highlighter-rouge">Map</code>, and <code class="language-plaintext highlighter-rouge">Object</code>, in addition to <code class="language-plaintext highlighter-rouge">Array</code>.</p>

<pre><code class="language-wdl">version 1.2

workflow test_length {
  Map[String, Int] m = {"a": 1, "b", 2}
  String s = "ABCDE"

  output {
    Int mlen = length(m)
    Int slen = length(s)
  }
}
</code></pre>

<p>Finally, the <a href="https://github.com/openwdl/wdl/blob/wdl-1.2/SPEC.md#read_tsv"><code class="language-plaintext highlighter-rouge">read_tsv</code></a> function now has a variant that reads field names either from a header row or an <code class="language-plaintext highlighter-rouge">Array[String]</code> and returns an <code class="language-plaintext highlighter-rouge">Array[Object]</code>.</p>

<pre><code class="language-wdl">version 1.2

task read_tsv {
  command &lt;&lt;&lt;
    {
      printf "row1\tvalue1\n"
      printf "row2\tvalue2\n"
      printf "row3\tvalue3\n"
    } &gt;&gt; data.no_headers.tsv

    {
      printf "header1\header2\n"
      printf "row1\tvalue1\n"
      printf "row2\tvalue2\n"
      printf "row3\tvalue3\n"
    } &gt;&gt; data.headers.tsv
  &gt;&gt;&gt;

  output {
    Array[Array[String]] output_table = read_tsv("data.no_headers.tsv")
    Array[Object] output_objs1 = read_tsv("data.no_headers.tsv", false, ["name", "value"])
    Array[Object] output_objs2 = read_tsv("data.headers.tsv", true)
    Array[Object] output_objs3 = read_tsv("data.headers.tsv", true, ["name", "value"])
  }
}
</code></pre>

<h2 id="multi-line-strings">Multi-line Strings</h2>

<p>Previously, wrapping a long string over multiple lines required breaking it into multiple strings and concatenating it.</p>

<p>WDL 1.2 introduces <a href="https://github.com/openwdl/wdl/blob/wdl-1.2/SPEC.md#multi-line-strings">multi-line strings</a>, which have the same syntax and whitespace handling behavior as the task <code class="language-plaintext highlighter-rouge">command</code> section.</p>

<pre><code class="language-wdl">version 1.2

workflow multiline_strings1 {
  output {
    String s = &lt;&lt;&lt;
      This is a
      multi-line string!
    &gt;&gt;&gt;
  }
}
</code></pre>

<h2 id="struct-enhancements">Struct Enhancements</h2>

<p>Structs can now have their own <code class="language-plaintext highlighter-rouge">meta</code> and <code class="language-plaintext highlighter-rouge">parameter_meta</code> sections, just like tasks and workflows.</p>

<p>It is <a href="https://github.com/openwdl/wdl/blob/wdl-1.2/SPEC.md#struct-to-struct-coercion">now allowed</a> to coerce between types from a struct value that includes a superset of keys in the target type. <strong>Note: This change might break existing workflows that rely on strict key matching.</strong></p>

<pre><code class="language-wdl">version 1.2

struct A {
  String s
}

Struct B {
  A a_struct
  Int i
}

struct C {
  String s
}

struct D {
  C a_struct
  Int i
}

workflow struct_to_struct {
  B my_b = B {
    a_struct: A { s: 'hello' },
    i: 10
  }
  # We can coerce `my_b` from type `B` to type `D` because `B` and `D`
  # have members with the same names and compatible types. Type `A` can
  # be coerced to type `C` because they also have members with the same
  # names and compatible types.
  
  output {
    D my_d = my_b
  }
}
</code></pre>

<h2 id="the-call-input-clause-is-optional">The Call <code class="language-plaintext highlighter-rouge">input:</code> Clause is Optional</h2>

<p>A minor but much-requested change in WDL 1.2 is to make the <code class="language-plaintext highlighter-rouge">input:</code> clause optional in <code class="language-plaintext highlighter-rouge">call</code>s.</p>

<pre><code class="language-wdl">version 1.2

task repeat {
  input {
    Int i = 5
    String? value
  }
  
  command &lt;&lt;&lt;
  for i in 1..~{i}; do
    printf ~{select_first([value, "default"])}
  done
  &gt;&gt;&gt;

  output {
    Array[String] lines = read_lines(stdout())
  }
}

workflow call_example {
  input {
    Int i
  }

  # Calls repeat with one required input - it is okay to not
  # specify a value for repeat.value since it is optional.
  call repeat { i = i }

  # Since the workflow and task inputs have the same name, we
  # can make the call even simpler:
  call repeat as repeat2 { i }
}
</code></pre>

<h2 id="clarifications">Clarifications</h2>

<p>WDL 1.2 provides clarification of some parts of the spec that were previously confusing or under-specified:</p>

<ul>
  <li>Input files and directories should be treated as read-only. Workflow engine implementers are encouraged to enforce this behavior.</li>
  <li>Local (i.e., post-localization) paths are always used when evaluating an expression for an input, private variable, or command section.</li>
  <li>Accessing a non-existent member of an object, struct, or call is now explicitly defined as an error.</li>
  <li><a href="https://github.com/openwdl/wdl/blob/wdl-1.2/SPEC.md#optional-inputs-with-defaults">Inputs with default expressions are implicitly optional</a>.</li>
</ul>

<h2 id="conclusions">Conclusions</h2>

<p>These updates not only enhance the functionality of WDL but also improve its robustness and usability, making it easier to write, maintain, and run complex workflows. We encourage the community to explore these new features and provide feedback.</p>

<p>For detailed documentation and examples, visit the <a href="https://github.com/openwdl/wdl">OpenWDL GitHub repository</a>.</p>

<p>If you find other areas of the specification that you think need improvement, we welcome issues and pull requests. Stay tuned for more updates and happy coding!</p>]]></content><author><name>Venkat Malladi, John Didion</name></author><category term="wdl" /><category term="bioinformatics" /><category term="workflows" /><summary type="html"><![CDATA[Announcing WDL 1.2.0 Release]]></summary></entry><entry><title type="html">Workflow Template Repository</title><link href="https://vsmalladi.github.io/openwdl.github.io//wdl/bioinformatics/workflows/ci/cd/testing/wdl-template/" rel="alternate" type="text/html" title="Workflow Template Repository" /><published>2024-04-25T16:02:15+00:00</published><updated>2024-04-25T16:02:15+00:00</updated><id>https://vsmalladi.github.io/openwdl.github.io//wdl/bioinformatics/workflows/ci/cd/testing/wdl-template</id><content type="html" xml:base="https://vsmalladi.github.io/openwdl.github.io//wdl/bioinformatics/workflows/ci/cd/testing/wdl-template/"><![CDATA[<h1 id="a-comprehensive-guide-to-utilizing-workflow-templates-in-wdl-development">A Comprehensive Guide to Utilizing Workflow Templates in WDL Development</h1>

<p>Are you a developer looking to streamline your workflow in WDL (Workflow Description Language) development? Look no further than the <a href="https://github.com/openwdl/workflow-template-wdl">Workflow Template WDL repository</a>. This comprehensive guide will walk you through the repository’s features, from setting up a new project to running tests and ensuring seamless integration with essential tools like MiniWDL, Cromwell, and more.</p>

<h2 id="understanding-repository-templates">Understanding Repository Templates</h2>

<p>Before delving into the specifics of the Workflow Template WDL repository, let’s understand what sets it apart from a traditional fork. When you create a repository from a template, you’re not simply copying the codebase. Instead, you’re initiating a new project with a clean slate. This means:</p>

<ol>
  <li>
    <p><strong>Single Commit History</strong>: Unlike forks that inherit the entire commit history of the parent repository, projects created from a template start with a single commit. This ensures a fresh start for your project.</p>
  </li>
  <li>
    <p><strong>Contributions Graph</strong>: Commits made to a repository created from a template will reflect in your contributions graph, offering clear visibility of your project contributions.</p>
  </li>
  <li>
    <p><strong>New Project Initiation</strong>: Utilizing a repository template is ideal for starting a new project swiftly, without the baggage of unnecessary commit history.</p>
  </li>
</ol>

<h2 id="devcontainer-configuration-for-seamless-development">Devcontainer Configuration for Seamless Development</h2>

<p>One of the standout features of the repository is its Devcontainer configuration. This configuration sets up a GitHub Codespace tailored for WDL development. The Devcontainer includes essential tools such as VScode, Docker, MiniWDL, Cromwell, WOMTool, Sprocket, and more, ensuring a seamless development experience.</p>

<h2 id="dockstore-template-for-automated-workflow-registration">Dockstore Template for Automated Workflow Registration</h2>

<p>Managing workflows becomes hassle-free with the included <a href="https://dockstore.org/">Dockstore</a> template. Automatic registration of your workflow using the <a href="https://docs.dockstore.org/en/stable/getting-started/github-apps/github-apps-landing-page.html">Dockstore GitHub App</a> simplifies the process, allowing you to focus on your project’s core functionality.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># Dockstore config version, not pipeline version
# Visit for full list of fields: https://docs.dockstore.org/en/stable/assets/templates/workflows/workflows.html#full-template-with-explanation-of-all-available-fields
version: 1.2
workflows:
  - subclass: WDL
    publish: True
    primaryDescriptorPath: /hello.wdl # Change to point to your pipeline wdl
    testParameterFiles:
    authors:
      - orcid: &lt;String&gt; # Add authors
    name: hello
</code></pre></div></div>

<h2 id="unit-and-integration-testing-made-eas">Unit and Integration Testing Made Eas</h2>

<p>Testing is a crucial aspect of any development workflow, and the  repository makes it a breeze. With <a href="https://pytest-workflow.readthedocs.io/">pytest-workflow</a> for unit and integration tests, you can ensure the reliability and functionality of your WDL code. Examples for unit and integration tests are provided within the repository, guiding you through the testing process effortlessly.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>version 1.0

task hello {
  input {
    String name
  }

  command {
    echo 'hello ${name}!'
  }

  output {
    File response = stdout()
  }

  runtime {
   docker: 'ubuntu:22.04'
  }

  parameter_meta {
    name: {
      help: "String to echo for task"
    }
  }
}

workflow example {
  call hello
}
</code></pre></div></div>

<p>Unit test of Hello Task</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>- name: test-hello
  command: miniwdl run -i tests/inputs/hello.inputs.json -d test-output/ --task hello hello.wdl
  files:
    - path: test-output/_LAST/stdout.txt
      contains:                        
        - 'hello Test!'
</code></pre></div></div>

<h2 id="verification-and-setup">Verification and Setup</h2>

<p>The repository offers clear instructions for verifying and setting up your development environment. From testing MiniWDL and Cromwell installations to ensuring correct setup of tools like sprocket, every step is meticulously outlined, guaranteeing a smooth start to your project.</p>

<h2 id="conclusion">Conclusion</h2>

<p>In conclusion, the Workflow Template WDL repository provides a robust foundation for WDL development projects. Whether you’re a seasoned developer or just starting with WDL, this repository offers the tools and guidance needed to kickstart your projects efficiently. By leveraging the Devcontainer configuration, Dockstore template, and comprehensive testing suite, you can streamline your development workflow and focus on building innovative solutions.</p>

<p>With clear documentation, easy setup instructions, and a supportive community of contributors, embarking on your next WDL project has never been easier. So why wait? Dive into the Workflow Template WDL repository and unleash the full potential of your WDL development endeavors.</p>]]></content><author><name>Venkat Malladi</name></author><category term="wdl" /><category term="bioinformatics" /><category term="workflows" /><category term="ci" /><category term="cd" /><category term="testing" /><summary type="html"><![CDATA[A Comprehensive Guide to Utilizing Workflow Templates in WDL Development]]></summary></entry><entry><title type="html">Announcing WDL 1.1.2</title><link href="https://vsmalladi.github.io/openwdl.github.io//wdl/bioinformatics/workflows/announcing-wdl-1-1-2/" rel="alternate" type="text/html" title="Announcing WDL 1.1.2" /><published>2024-04-15T17:02:15+00:00</published><updated>2024-04-15T17:02:15+00:00</updated><id>https://vsmalladi.github.io/openwdl.github.io//wdl/bioinformatics/workflows/announcing-wdl-1-1-2</id><content type="html" xml:base="https://vsmalladi.github.io/openwdl.github.io//wdl/bioinformatics/workflows/announcing-wdl-1-1-2/"><![CDATA[<h1 id="announcing-wdl-112-release">Announcing WDL 1.1.2 Release</h1>

<p>The <a href="https://openwdl.org/">OpenWDL</a> community is pleased to announce the release of <a href="https://github.com/openwdl/wdl/blob/wdl-1.1/SPEC.md">Workflow Description Language (WDL) 1.1.2</a>!</p>

<p>This is a small release with only a few clarifications to the WDL 1.1 specification:</p>

<ul>
  <li>It is now <a href="https://github.com/openwdl/wdl/blob/wdl-1.1/SPEC.md#binary-operators-on-primitive-types">explicitly stated</a> that boolean expressions have “short-circuiting” behavior, i.e.
    <ul>
      <li>For <code class="language-plaintext highlighter-rouge">A &amp;&amp; B</code>, if <code class="language-plaintext highlighter-rouge">A</code> evalutes to <code class="language-plaintext highlighter-rouge">false</code> then <code class="language-plaintext highlighter-rouge">B</code> is not evaluated.</li>
      <li>For <code class="language-plaintext highlighter-rouge">A || B</code>, if <code class="language-plaintext highlighter-rouge">A</code> evaluates to <code class="language-plaintext highlighter-rouge">true</code> then <code class="language-plaintext highlighter-rouge">B</code> is not evaluated.</li>
    </ul>
  </li>
  <li>It is now <a href="https://github.com/openwdl/wdl/blob/wdl-1.1/SPEC.md#read_boolean">explicitly stated</a> that the <code class="language-plaintext highlighter-rouge">read_boolean</code> function is case-insensitive.</li>
  <li>It is now stated that the <a href="https://github.com/openwdl/wdl/blob/wdl-1.1/SPEC.md#union">Union type</a> that was <a href="https://openwdl.org/wdl/bioinformatics/workflows/announcing-wdl-1-1-1/#hidden-types">introduced in WDL 1.1.1</a> is also the type of <code class="language-plaintext highlighter-rouge">runtime</code> attributes that accept multiple types of values (e.g. <a href="https://github.com/openwdl/wdl/blob/wdl-1.1/SPEC.md#memory"><code class="language-plaintext highlighter-rouge">memory</code></a>, which an accept an <code class="language-plaintext highlighter-rouge">Int</code> or <code class="language-plaintext highlighter-rouge">String</code>).</li>
  <li>Clay McLeod contributed a PR to improve the descriptions of <a href="https://github.com/openwdl/wdl/blob/wdl-1.1/SPEC.md#read_boolean"><code class="language-plaintext highlighter-rouge">task</code></a>s and <a href="https://github.com/openwdl/wdl/blob/wdl-1.1/SPEC.md#read_boolean"><code class="language-plaintext highlighter-rouge">workflow</code></a>s to make it explicit the number of times each element is allowed.</li>
  <li>We added to the <a href="https://github.com/openwdl/wdl/blob/wdl-1.1/RFC.md">RFC guidelines</a> that every signficant addition or change to the specification now requires <a href="https://github.com/openwdl/wdl/blob/wdl-1.1/tests/README.md">accompanying test cases</a> to be accepted.</li>
</ul>

<p>If you find other areas of the specification that you think need improvement, we welcome <a href="https://github.com/openwdl/wdl/issues">issues</a> and <a href="https://github.com/openwdl/wdl/pulls">pull requests</a>.</p>]]></content><author><name>John Didion</name></author><category term="wdl" /><category term="bioinformatics" /><category term="workflows" /><summary type="html"><![CDATA[Announcing WDL 1.1.2 Release]]></summary></entry><entry><title type="html">New Website Design</title><link href="https://vsmalladi.github.io/openwdl.github.io//wdl/bioinformatics/workflows/website/documentation/new-website/" rel="alternate" type="text/html" title="New Website Design" /><published>2024-01-25T21:24:15+00:00</published><updated>2024-01-25T21:24:15+00:00</updated><id>https://vsmalladi.github.io/openwdl.github.io//wdl/bioinformatics/workflows/website/documentation/new-website</id><content type="html" xml:base="https://vsmalladi.github.io/openwdl.github.io//wdl/bioinformatics/workflows/website/documentation/new-website/"><![CDATA[<h1 id="openwdl-website-redesigned">OpenWDL Website Redesigned</h1>

<p>We are excited to announce the fresh and improved look of the <a href="https://www.openwdl.org">OpenWDL website</a>! The community has worked diligently to revamp the website, focusing on a clean design and minimizing any potential mistakes in the user experience.</p>

<h2 id="whats-new">What’s New?</h2>

<h3 id="sleek-design">Sleek Design</h3>

<p>The redesigned website comes with a sleek and modern design, providing a more intuitive and visually appealing experience for our users. The layout has been optimized to enhance navigation and make it easier for visitors to find the information they need.</p>

<h3 id="improved-navigation">Improved Navigation</h3>

<p>Finding your way around the OpenWDL website is now more straightforward than ever. The navigation has been improved to help users quickly locate documentation, resources, and other essential information.</p>

<h2 id="why-the-change">Why the Change?</h2>

<p>The decision to redesign the website stemmed from our commitment to providing an exceptional user experience. We wanted to create a platform that not only showcases the power of Workflow Description Language (WDL) but also does so with clarity and precision.</p>

<p>By streamlining the design, we aim to make the OpenWDL website a go-to resource for individuals interested in WDL, whether they are newcomers or seasoned users.</p>

<h2 id="explore-the-new-look">Explore the New Look!</h2>

<p>We invite you to explore the redesigned OpenWDL website and discover the improvements we’ve made. Your feedback is valuable to us, so feel free to share your thoughts and suggestions. We are dedicated to continually enhancing the website to better serve the needs of the OpenWDL community.</p>

<p>Visit the <a href="https://www.openwdl.org">OpenWDL Website</a> and experience the changes firsthand.</p>

<h2 id="get-involved">Get Involved!</h2>

<p>As a community-driven project, OpenWDL thrives on collaboration and input from its users. If you have ideas for further improvements or if you spot any issues, please don’t hesitate to reach out. Your involvement is crucial to the success and ongoing development of OpenWDL. Interactions occur primarily on <a href="https://github.com/openwdl/wdl">GitHub</a> and <a href="https://join.slack.com/t/openwdl/shared_invite/zt-ctmj4mhf-cFBNxIiZYs6SY9HgM9UAVw">Slack</a>. Please see the <a href="https://github.com/openwdl/wdl/tree/wdl-1.1#community-and-support">README</a> for the full list of community resources.</p>

<h3 id="blog">Blog</h3>

<p>We have a new <a href="https://www.openwdl.org/blog">Blog</a> that we will be putting more frequent updates. We encourage the community to add to their experience.</p>

<p>Stay tuned for more updates, and happy exploring on the redesigned OpenWDL website!</p>]]></content><author><name>Venkat Malladi</name></author><category term="wdl" /><category term="bioinformatics" /><category term="workflows" /><category term="website" /><category term="documentation" /><summary type="html"><![CDATA[OpenWDL Website Redesigned]]></summary></entry><entry><title type="html">Announcing WDL 1.1.1</title><link href="https://vsmalladi.github.io/openwdl.github.io//wdl/bioinformatics/workflows/announcing-wdl-1-1-1/" rel="alternate" type="text/html" title="Announcing WDL 1.1.1" /><published>2023-12-16T17:02:15+00:00</published><updated>2023-12-16T17:02:15+00:00</updated><id>https://vsmalladi.github.io/openwdl.github.io//wdl/bioinformatics/workflows/announcing-wdl-1-1-1</id><content type="html" xml:base="https://vsmalladi.github.io/openwdl.github.io//wdl/bioinformatics/workflows/announcing-wdl-1-1-1/"><![CDATA[<h1 id="announcing-wdl-111-release">Announcing WDL 1.1.1 Release</h1>

<p>The <a href="https://openwdl.org/">OpenWDL</a> community is pleased to announce the release of <a href="https://github.com/openwdl/wdl/blob/wdl-1.1/SPEC.md">Workflow Description Language (WDL) 1.1.1</a>! This post highlights the most important changes in this release.</p>

<h2 id="about-wdl">About WDL</h2>

<p>If you’re new to WDL, it is an open standard for describing data processing workflows with a human-readable and writable syntax. It is designed for accessibility, portability, and efficiency. There are several <a href="https://github.com/openwdl/wdl/tree/wdl-1.1#execution-engines-and-platforms">implementations</a> to choose from that run in a variety of environments, including HPC systems and cloud platforms.</p>

<h2 id="whats-new">What’s new?</h2>

<p>This patch release addresses many issues with the clarity of the specification that have been raised by the community and also adds some improvements to its readability and utility. Note that this release does not introduce any new features or change any existing functionality.</p>

<h3 id="example-or-test-case-why-not-both">Example or Test Case? Why Not Both?</h3>

<p>The biggest improvement introduced in this release is to the examples. Every example has been reviewed (and updated if necessary) to ensure that it is valid, executable WDL. In addition, nearly every example has been converted to a <a href="https://github.com/openwdl/wdl-tests/blob/main/docs/MarkdownTests.md">standardized format</a> that enables it to be used as a test case. If you see an arrow (►) next to the title of an example, you can click it to view inputs that can be used to run the example, as well as the expected outputs.</p>

<p><img src="/assets/images/unit-test.png" alt="unit-test" /></p>

<p><strong>An example that is also a test case</strong></p>

<p>We invite the community to contribute additional test cases to the <a href="https://github.com/openwdl/wdl-tests">WDL Tests</a> repository. Our eventual goal is to curate the specification-derived and the contributed tests into a compliance suite that can be used to validate implementations.</p>

<h3 id="hidden-types">Hidden Types</h3>

<p>WDL is a strongly typed language - every variable, function parameter, and return value has a <a href="https://github.com/openwdl/wdl/blob/wdl-1.1/SPEC.md#types">type</a>, and implementations perform static analysis to ensure that assigned values are of the correct type. However, the WDL type system has some <a href="https://github.com/openwdl/wdl/issues/373">quirks and inconsistencies</a> that the community has been working to address.</p>

<p><a href="https://github.com/openwdl/wdl/blob/wdl-1.1/SPEC.md#hidden-types">Hidden Types</a> are a new concept added in this release to better explain some existing behavior that many users have found confusing. A hidden type is one that may only be instantiated by the execution engine and cannot be used in a declaration within a WDL file.</p>

<p>Currently, there is only one hidden type, Union, that represents a value that may have any one of several concrete types. A Union value must always be coerced to a concrete type. There are two places where the Union type is used:</p>

<ol>
  <li>It is the type of the special <a href="https://dev.to/openwdl/announcing-wdl-111-ccj#:~:text=of%20the%20special-,None,-value%2C%20which%20can"><code class="language-plaintext highlighter-rouge">None</code></a> value, which can be assigned to an Optional of any type.</li>
  <li>It is the return type of the <a href="https://github.com/openwdl/wdl/blob/wdl-1.1/SPEC.md#read_json"><code class="language-plaintext highlighter-rouge">read_json</code></a> standard library function, which returns a different type of value depending on the contents of the JSON file.</li>
</ol>

<p>In the next major version of WDL (2.0), the <code class="language-plaintext highlighter-rouge">Object</code> type will also become hidden. Previously, the <code class="language-plaintext highlighter-rouge">Object</code> type - as well as all functions that took an <code class="language-plaintext highlighter-rouge">Object</code> parameter and/or had an <code class="language-plaintext highlighter-rouge">Object</code> return type - were marked as deprecated. Since an <code class="language-plaintext highlighter-rouge">Object</code>’s contents are determined at runtime, it is opaque to static analysis. It is better to instead use <a href="https://github.com/openwdl/wdl/blob/wdl-1.1/SPEC.md#custom-types-structs">structs</a> in which the names and types of members are declared explicitly. However, we came to recognize that <code class="language-plaintext highlighter-rouge">Object</code> and the related standard library functions still offer utility. Thus, in WDL 1.1.1, those standard library functions have been “un-deprecated” and will remain in the standard library going forward.</p>

<h3 id="a-more-organized-standard-library">A More Organized Standard Library</h3>

<p>WDL has a <a href="https://github.com/openwdl/wdl/blob/wdl-1.1/SPEC.md#standard-library">standard library</a> of nearly 50 functions to perform some of the most commonly needed operations in data processing workflows. Previously, the specification simply presented all of these functions in a big list without much rhyme or reason to its organization, and it was difficult to find the right function if you didn’t already know its name. In WDL 1.1.1, the functions have been ordered by argument type to make it easier to find what you need.</p>

<h3 id="a-branch-for-every-version">A Branch for Every Version</h3>

<p>In addition to specification changes, the organization of the GitHub repository is also changing. The current version of the repository (the <code class="language-plaintext highlighter-rouge">main</code> branch, also tagged as <a href="https://github.com/openwdl/wdl/tree/legacy"><code class="language-plaintext highlighter-rouge">legacy</code></a>) is now read-only. Going forward, each version of the specification will have its own permanent branch (beginning with <a href="https://github.com/openwdl/wdl/tree/wdl-1.1"><code class="language-plaintext highlighter-rouge">wdl-1.1</code></a>). On GitHub, the default branch (the one you see when you go to <a href="https://github.com/openwdl/wdl">https://github.com/openwdl/wdl</a>) will always be set to the branch for the current version of the specification.</p>

<p>If you compare the legacy and current branches, you’ll notice that the organization of files and directories has also changed. Some folders (<code class="language-plaintext highlighter-rouge">highlighters</code>, <code class="language-plaintext highlighter-rouge">runners</code>, <code class="language-plaintext highlighter-rouge">scripts</code>) were largely vestigial and have been removed completely, with any still-relevant content moved to the <a href="https://github.com/openwdl/wdl/blob/wdl-1.1/README.md"><code class="language-plaintext highlighter-rouge">README</code></a>. The grammars and parsers now have <a href="https://github.com/openwdl/wdl-parsers">their own repository</a>. And there is no longer a <code class="language-plaintext highlighter-rouge">versions</code> directory; instead, each branch is specific to a single version of the specification, which lives in the root directory (older versions of the specification are preserved in the <code class="language-plaintext highlighter-rouge">main</code> branch).</p>

<p>These changes to the repository have implications for linking and for submitting pull requests.</p>

<h2 id="whats-next">What’s Next?</h2>

<p>The WDL community is already hard at work on <a href="https://github.com/openwdl/wdl/discussions/473">WDL 1.2</a>, which is planned for release in 2024. Importantly, this release includes all non-breaking changes from the development version of the specification. Stay tuned for another post highlighting those upcoming changes.</p>

<p>The community is also working on WDL 2.0 (also called development). This is the next major version of the specification and will introduce some breaking changes intended to improve the language for the long-term.</p>

<h2 id="reach-out">Reach out!</h2>

<p>The WDL community depends on your involvement to thrive. You are encouraged to ask questions, help other users, and make contributions where you can. Interactions occur primarily on <a href="https://github.com/openwdl/wdl">GitHub</a> and <a href="https://join.slack.com/t/openwdl/shared_invite/zt-ctmj4mhf-cFBNxIiZYs6SY9HgM9UAVw">Slack</a>. Please see the <a href="https://github.com/openwdl/wdl/tree/wdl-1.1#community-and-support">README</a> for the full list of community resources.</p>]]></content><author><name>John Didion</name></author><category term="wdl" /><category term="bioinformatics" /><category term="workflows" /><summary type="html"><![CDATA[Announcing WDL 1.1.1 Release]]></summary></entry></feed>