Skip to content

Add manifest.diagram to the pipeline template, with linting - #4460

Open
ewels wants to merge 6 commits into
nf-core:devfrom
ewels:manifest-diagram
Open

Add manifest.diagram to the pipeline template, with linting#4460
ewels wants to merge 6 commits into
nf-core:devfrom
ewels:manifest-diagram

Conversation

@ewels

@ewels ewels commented Sep 4, 2026

Copy link
Copy Markdown
Member

Nextflow recently added manifest.diagram: a relative path to the pipeline's workflow diagram. It lands in Nextflow 26.10. Older versions ignore unknown manifest fields, so it's safe to set in any pipeline today.

Template

Adds the field to nextflow.config, commented out with a TODO, since a brand new pipeline has no metro map yet:

// TODO nf-core: Make a metro map (nf-metro or drawn) and add relative path to the SVG below
// diagram      = 'docs/images/metro_map.svg'

nf-metro is mentioned as a recommendation, not a requirement — any SVG works, however you make it.

Linting

Both checks live in the existing nextflow_config lint test rather than a new one:

  • Warning if manifest.diagram is not set. A freshly created pipeline gets this warning until the author draws a map, alongside the other template TODO warnings.
  • Failure if it is set but is a URL rather than a relative path, is not one of the image formats Nextflow accepts (.svg, .png, .jpg, .jpeg, .gif, .webp), or points at a file that isn't in the repository.

The lint docs are generated from the test's docstring, which is updated to cover both.

Since a new pipeline now always produces the missing-diagram warning, the existing assert len(result["warned"]) == 0 assertions in test_nextflow_config.py now assert that this is the only warning. Four new tests cover the valid path, missing file, unsupported format and URL cases.

CI

create-lint-wf and create-test-lint-wf-template lint the generated test pipeline with --fail-warned, so the missing-diagram warning would fail those jobs. Both now create a placeholder docs/images/metro_map.svg and uncomment the diagram line first, in the same way they already neutralise the template TODOs and includeConfig.

Pipelines themselves are unaffected: the template's linting.yml doesn't use --fail-warned, so authors get the nudge as a warning.

Docs

The nf-core website side is in nf-core/website#4390 — a new section on the workflow schematics page.

PR checklist

  • This comment contains a description of changes (with reason)
  • CHANGELOG.md is updated
  • If you've fixed a bug or added code that should be tested, add tests!
  • Documentation in docs is updated

Nextflow 26.10 adds `manifest.diagram`, a relative path to the pipeline's
workflow diagram. Older versions ignore unknown manifest fields, so it is
safe to set in any pipeline.

The template ships the field commented out with a TODO, since a new pipeline
has no metro map yet. Linting warns when it is missing and fails when it is
set to a URL or to a path that does not exist in the repository.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@codecov

codecov Bot commented Sep 4, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 78.21%. Comparing base (d08b348) to head (b6e2d5b).

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment thread nf_core/pipeline-template/nextflow.config Outdated
ewels and others added 3 commits September 4, 2026 11:11
Nextflow accepts image/svg+xml, image/png, image/jpeg, image/gif and
image/webp, so fail on any other file extension.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
These jobs lint with `--fail-warned`, so the missing-diagram warning that a
new pipeline is meant to get becomes a failure. Neutralise it the same way
the workflows already handle the template TODOs and `includeConfig`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Comment thread nf_core/pipeline-template/nextflow.config
Comment thread nf_core/pipelines/lint/nextflow_config.py
@ewels

ewels commented Sep 4, 2026

Copy link
Copy Markdown
Member Author

This is what happens if you run a pipeline with this config setting in a version of Nextflow that doesn't support it:

nextflow run ./demo --help

 N E X T F L O W   ~  version 26.04.6

Downloading plugin nf-schema@2.7.2
Launching `./demo/main.nf` [lonely_moriondo] revision: f6f57a9eb7

WARN: Unrecognized config option 'manifest.diagram'

------------------------------------------------------
                                        ,--./,-.
        ___     __   __   __   ___     /,-._.--~'
  |\ | |__  __ /  ` /  \ |__) |__         }  {
  | \| |       \__, \__/ |  \ |___     \`-._,-`-,
                                        `._,._,'
  nf-core/demo 1.2.0
------------------------------------------------------

With strict syntax off (old language parser) there's nothing at all:

NXF_SYNTAX_PARSER=v1 nextflow run ./demo --help

 N E X T F L O W   ~  version 26.04.6

Launching `./demo/main.nf` [festering_rubens] revision: f6f57a9eb7


------------------------------------------------------
                                        ,--./,-.
        ___     __   __   __   ___     /,-._.--~'
  |\ | |__  __ /  ` /  \ |__) |__         }  {
  | \| |       \__, \__/ |  \ |___     \`-._,-`-,
                                        `._,._,'
  nf-core/demo 1.2.0
------------------------------------------------------

@ewels

ewels commented Sep 4, 2026

Copy link
Copy Markdown
Member Author

Looks good on a wider sweep of Nextflow versions (was worried briefly, but turns out that the error I saw at first was because my version of Java was too new for the old Nextflow version)

Stuff breaks badly if you try to access the config attribute within the pipeline (eg. println workflow.manifest.diagram), but just having it there should be fine, beyond a warning log or two:


All runs below on JDK 21 (JDK 17 for ≤23.04). Exit code 0 everywhere, workflow ran, no version failed.

Nextflow With diagram Why
21.10.6 – 25.04.8 WARN: Invalid config manifest attribute 'diagram' (printed twice) Manifest(Map) loops over keys, warns on anything not a getter
25.10.0 – 25.10.7 silent Manifest rewritten as a ConfigScope with explicit field assignment — unknown keys just fall on the floor
26.04.6, 26.08.0-edge WARN: Unrecognized config option 'manifest.diagram' (once) new ConfigValidator, gated on if( NF.isSyntaxParserV2() ) in CmdRun/CmdConfig — hence NXF_SYNTAX_PARSER=v1 silences it

@muffato

muffato commented Sep 4, 2026

Copy link
Copy Markdown
Member

Does this key support defining light-/dark-background images ? We generate all diagrams in both themes (same content, so could pick either)

@pinin4fjords

Copy link
Copy Markdown
Member

Does this key support defining light-/dark-background images ? We generate all diagrams in both themes (same content, so could pick either)

This did occur to me when I was writing that Nextflow PR, but I went with a single value proposition on the assumption that we could make SVGs that worked well enough in light and dark.

@ewels

ewels commented Sep 4, 2026

Copy link
Copy Markdown
Member Author

SVGs that worked well enough in light and dark.

To elaborate: SVGs can have CSS variable colours that detect the host operating system's light / dark mode. So you can have white text or black text according to that. nf-metro does this by default, I believe. We can write some docs on the concept too.

It's not always super straightforward, eg. if a website's theme is set to light but the OS is dark, but generally it works pretty well. And it is possible to overcome this edge case if needed, with a bit of cleverness.

Worst case, we can just chuck in a non-transparent background to the image and it should be safe everywhere.

@codspeed-hq

This comment was marked as off-topic.

@muffato

muffato commented Sep 4, 2026

Copy link
Copy Markdown
Member

nf-metro does this by default, I believe.

Ah, I didn't know that. I generate two versions every time 🤦🏼

@ewels

ewels commented Sep 4, 2026

Copy link
Copy Markdown
Member Author

Yes, not sure how new this feature is @pinin4fjords ?

New docs at least, as of today that explain how it works: https://seqeralabs.github.io/nf-metro/dev/theming/

@SPPearce

SPPearce commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

I agree with Phil here, I think it is fine to include the link to nf-metro.

@SPPearce SPPearce left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks fine to me, but I'm not a python expert.

nextflowVersion = '!>=25.10.4'
version = '{{ version }}'
doi = ''
// TODO nf-core: Make a metro map (nf-metro or drawn) and add relative path to the SVG below

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be a link to our docs https://nf-co.re/docs/community/brand/workflow-schematics which need to be updated with nf-metro)


def test_manifest_diagram_pass(self):
"""Test that a `manifest.diagram` pointing at an existing file passes."""
diagram = Path(self.new_pipeline) / "docs" / "images" / "metro_map.svg"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
diagram = Path(self.new_pipeline) / "docs" / "images" / "metro_map.svg"
diagram = self.new_pipeline / "docs" / "images" / "metro_map.svg"

is already path


# Check that manifest.diagram points at a file that exists in the pipeline
diagram = manifest.get("diagram", "")
if diagram and "manifest.diagram" not in ignore_configs:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are the ignore_configs now not also a nested dict?

nf_conf_file = Path(self.new_pipeline) / "nextflow.config"
content = nf_conf_file.read_text()
assert "// diagram" in content
nf_conf_file.write_text(content.replace("// diagram", f"diagram = '{value}' //"))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bit of a weird replace here because it leaves the placeholder string as a comment, but maybe the cleanest option

result = self._lint_new_pipeline()
assert f"Config ``manifest.diagram`` should be a relative path, not a URL: ``{url}``" in result["failed"]

def _set_manifest_diagram(self, value: str) -> None:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think we usually have helper functions higher up

f"Config ``manifest.diagram`` is not a supported image format "
f"({', '.join(sorted(DIAGRAM_EXTENSIONS))}): ``{diagram}``"
)
elif (Path(self.wf_path) / diagram).is_file():

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might be very minor: if the diagram is an absolute path it could override

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants